jQuery - Invocation illégale


108

jQuery v1.7.2

J'ai cette fonction qui me donne l'erreur suivante lors de l'exécution:

Uncaught TypeError: Illegal invocation

Voici la fonction:

$('form[name="twp-tool-distance-form"]').on('submit', function(e) {
    e.preventDefault();

    var from = $('form[name="twp-tool-distance-form"] input[name="from"]');
    var to = $('form[name="twp-tool-distance-form"] input[name="to"]');
    var unit = $('form[name="twp-tool-distance-form"] input[name="unit"]');
    var speed = game.unit.speed($(unit).val());

    if (!/^\d{3}\|\d{3}$/.test($(from).val()))
    {
        $(from).css('border-color', 'red');
        return false;
    }

    if (!/^\d{3}\|\d{3}$/.test($(to).val()))
    {
        $(to).css('border-color', 'red');
        return false;
    }

    var data = {
        from : from,
        to : to,
        speed : speed
    };

    $.ajax({
        url : base_url+'index.php',
        type: 'POST',
        dataType: 'json',
        data: data,
        cache : false
    }).done(function(response) {
        alert(response);
    });

    return false;
});

Si je supprime datade l'appel ajax, cela fonctionne .. des suggestions?

Merci!


essayez de supprimer fromdes données. Peut-être qu'il est en conflit avec jquery de
gopi1410

6
Vous réalisez que vous essayez de pousser des objets jQuery, pas JSON, non?
avocat

18
Cela m'arrive régulièrement quand j'oublie le .val () sur un objet jQuery ...
userfuser

Réponses:


118

Je pense que vous devez avoir des chaînes comme valeurs de données. C'est probablement quelque chose en interne dans jQuery qui n'encode / sérialise pas correctement les objets To & From.

Essayer:

var data = {
    from : from.val(),
    to : to.val(),
    speed : speed
};

Remarquez également sur les lignes:

$(from).css(...
$(to).css(

Vous n'avez pas besoin du wrapper jQuery car To & From sont déjà des objets jQuery.


2
Merci, j'ai oublié que j'avais chargé des objets au lieu de chaînes, généralement je charge des chaînes :)
yoda

3
Cette approche m'aide. Je nomme mes variables comme $from = $('#from');Cela m'aide à me souvenir qu'il représente un objet jQuery qui évite d'appeler une méthode sur quelque chose qui est une chaîne ou d'essayer de manipuler une chaîne avec .toString()ou quelque chose quand c'est un objet jQuery.
timbrown

J'avais la .val()pièce manquante, donc ça ne passait pas la valeur.
SharpC

109

Essayez de définir processData: false dans les paramètres ajax comme celui-ci

$.ajax({
    url : base_url+'index.php',
    type: 'POST',
    dataType: 'json',
    data: data,
    cache : false,
    processData: false
}).done(function(response) {
    alert(response);
});

8
By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false.
BOTJr.

Vous devrez peut-être également ajouter contentType: false. Je l'ai fait lors du téléchargement d'un fichier. Voir stackoverflow.com/questions/21044798/…
khylo

18

Pour mémoire, cela peut également arriver si vous essayez d'utiliser une variable non déclarée dans des données telles que

var layout = {};
$.ajax({
  ...
  data: {
    layout: laoyut // notice misspelled variable name
  },
  ...
});

1
Merci pour ça!! C'était totalement là que j'étais bloqué.
Matt Zelenak du

13

Si vous souhaitez soumettre un formulaire à l'aide de l' API Javascript FormData avec le téléchargement de fichiers, vous devez définir ci-dessous deux options:

processData: false,
contentType: false

Vous pouvez essayer comme suit:

//Ajax Form Submission
$(document).on("click", ".afs", function (e) {
    e.preventDefault();
    e.stopPropagation();
    var thisBtn = $(this);
    var thisForm = thisBtn.closest("form");
    var formData = new FormData(thisForm[0]);
    //var formData = thisForm.serializeArray();

    $.ajax({
        type: "POST",
        url: "<?=base_url();?>assignment/createAssignment",
        data: formData,
        processData: false,
        contentType: false,
        success:function(data){
            if(data=='yes')
            {
                alert('Success! Record inserted successfully');
            }
            else if(data=='no')
            {
                alert('Error! Record not inserted successfully')
            }
            else
            {
                alert('Error! Try again');
            }
        }
    });
});

Qu'est-ce que ces deux options, pourriez-vous expliquer?
rahim.nagori

2

Dans mon cas, je viens de changer

Remarque: c'est dans le cas de Django, j'ai donc ajouté csrftoken. Dans votre cas, vous n'en aurez peut-être pas besoin.

Ajouté contentType: false,processData: false

Commenté "Content-Type": "application/json"

$.ajax({
    url: location.pathname, 
    type: "POST",
    crossDomain: true,
    dataType: "json",
    headers: {
        "X-CSRFToken": csrftoken,
        "Content-Type": "application/json"
    },
    data:formData,
    success: (response, textStatus, jQxhr) => {

    },
    error: (jQxhr, textStatus, errorThrown) => {

    }
})

à

$.ajax({
    url: location.pathname, 
    type: "POST",
    crossDomain: true,
    dataType: "json",
    contentType: false,
    processData: false,
    headers: {
        "X-CSRFToken": csrftoken
        // "Content-Type": "application/json",
    },
    data:formData,
    success: (response, textStatus, jQxhr) => {

    },
    error: (jQxhr, textStatus, errorThrown) => {

    }
})

et cela a fonctionné.


2

Dans mon cas, je n'ai pas défini toutes les variables que je transmets aux données en ajax.

var page = 1;

$.ajax({
    url: 'your_url',
    type: "post",
    data: { 'page' : page, 'search_candidate' : search_candidate }
    success: function(result){
        alert('function called');
    }
)}

Je viens de définir la variable var search_candidate = "candidate name";et son fonctionnement.

var page = 1;
var search_candidate = "candidate name"; // defined
$.ajax({
    url: 'your_url',
    type: "post",
    data: { 'page' : page, 'search_candidate' : search_candidate }
    success: function(result){
        alert('function called');
    }
)}

0

Mon problème n'était pas lié à processData. C'est parce que j'ai envoyé une fonction qui ne peut pas être appelée plus tard applycar elle n'avait pas assez d'arguments. Plus précisément, je n'aurais pas dû utiliser alertcomme errorrappel.

$.ajax({
    url: csvApi,
    success: parseCsvs,
    dataType: "json",
    timeout: 5000,
    processData: false,
    error: alert
});

Consultez cette réponse pour plus d'informations sur les raisons pour lesquelles cela peut être un problème: Pourquoi certains appels de fonction sont-ils appelés «invocations illégales» en JavaScript?

La façon dont j'ai pu découvrir cela a été d'ajouter un console.log(list[ firingIndex ])à jQuery pour que je puisse suivre ce qu'il tirait.

C'était la solution:

function myError(jqx, textStatus, errStr) {
    alert(errStr);
}

$.ajax({
    url: csvApi,
    success: parseCsvs,
    dataType: "json",
    timeout: 5000,
    error: myError // Note that passing `alert` instead can cause a "jquery.js:3189 Uncaught TypeError: Illegal invocation" sometimes
});

0

Dans mon cas (en utilisant webpack 4) dans une fonction anonyme, que j'utilisais comme rappel.

J'ai dû utiliser window.$.ajax()au lieu de $.ajax()malgré avoir:

import $ from 'jquery';
window.$ = window.jQuery = $;

0

C'est aussi une cause aussi: Si vous avez construit une collection jQuery (via .map () ou quelque chose de similaire), vous ne devriez pas utiliser cette collection dans les données de .ajax (). Parce que c'est toujours un objet jQuery , pas un tableau JavaScript simple . Vous devez utiliser .get () au niveau de et pour obtenir le tableau js brut et l'utiliser sur le paramètre de données sur .ajax ().

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.