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!

yoda
la source
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.

LessQuesar
la source
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);
});
Justo
la source
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
  },
  ...
});
Ivan Ivanić
la source
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');
            }
        }
    });
});
Bablu Ahmed
la source
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é.

hygull
la source
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');
    }
)}
Rajesh Kharatmol
la source
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
});
ubershmekel
la source
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 = $;
Zanderwar
la source
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 ().

Burak TARHANLI
la source