jQuery - Niedozwolone wywołanie


108

jQuery v1.7.2

Mam tę funkcję, która powoduje następujący błąd podczas wykonywania:

Uncaught TypeError: Illegal invocation

Oto funkcja:

$('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;
});

Jeśli usunę dataz wywołania Ajax, to działa .. jakieś sugestie?

Dzięki!


spróbuj usunąć fromz danych. Może jest to sprzeczne z jquery z
— gopi1410,

6
Zdajesz sobie sprawę, że próbujesz przekazać obiekty jQuery, a nie JSON, prawda?
— asawyer

18
Zdarza mi się regularnie, kiedy zapomnę .val () na jakimś obiekcie jQuery ...
— userfuser

Odpowiedzi:


118

Myślę, że musisz mieć ciągi jako wartości danych. Prawdopodobnie jest to coś wewnętrznie w jQuery, co nie koduje / serializuje poprawnie obiektów To i From.

Próbować:

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

Zauważ również na liniach:

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

Nie potrzebujesz opakowania jQuery, ponieważ Do i Od są już obiektami jQuery.


2
Dzięki, zapomniałem, że ładowałem obiekty zamiast łańcuchów, zwykle ładuję łańcuchy :)
— yoda

3
Takie podejście mi pomaga. Nazywam swoje zmienne jako $from = $('#from');To pomaga mi zapamiętać, że reprezentuje obiekt jQuery, co pomaga uniknąć wywoływania metody na czymś, co jest ciągiem znaków lub próbach manipulowania łańcuchem .toString()lub czymś, gdy jest to obiekt jQuery.
— timbrown

.val()Brakowało mi części, więc nie przekazywała wartości.
— SharpC

109

Spróbuj ustawić processData: false w ustawieniach Ajax, takich jak to

$.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.

Konieczne może być również dodanie contentType: false. Zrobiłem podczas przesyłania pliku. Zobacz stackoverflow.com/questions/21044798/…
— khylo

18

Dla przypomnienia może się to również zdarzyć, jeśli spróbujesz użyć niezadeklarowanej zmiennej w danych, takich jak

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

1
Dziękuję za to!! To było miejsce, w którym byłem blokowany.
— Matt Zelenak

13

Jeśli chcesz przesłać formularz przy pomocy Javascript FormData API z wgrywaniem plików musisz ustawić poniżej dwie opcje:

processData: false,
contentType: false

Możesz spróbować w następujący sposób:

//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');
            }
        }
    });
});

Co robią te dwie opcje, czy możesz wyjaśnić?
— rahim.nagori

2

W moim przypadku po prostu się zmieniłem

Uwaga: tak jest w przypadku Django, więc dodałem csrftoken. W twoim przypadku możesz go nie potrzebować.

Dodano contentType: false,processData: false

Skomentowane "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) => {

    }
})

do

$.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) => {

    }
})

i zadziałało.


2

W moim przypadku nie zdefiniowałem wszystkich zmiennych, które przekazuję do danych w Ajax.

var page = 1;

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

Właśnie zdefiniowałem zmienną var search_candidate = "candidate name";i jej działanie.

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

Mój problem nie był związany processData. Było tak, ponieważ wysłałem funkcję, której nie można później wywołać, applyponieważ nie ma wystarczającej liczby argumentów. W szczególności nie powinienem był używać alertjako erroroddzwaniania.

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

Zobacz tę odpowiedź, aby uzyskać więcej informacji na temat tego, dlaczego może to być problem: Dlaczego niektóre wywołania funkcji są określane w JavaScript jako „nielegalne wywołania”?

Sposób, w jaki mogłem to odkryć, polegał na dodaniu a console.log(list[ firingIndex ])do jQuery, aby móc śledzić, co uruchamia.

To była poprawka:

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

W moim przypadku (używając webpacka 4) w ramach anonimowej funkcji, której używałem jako callback.

Musiałem użyć window.$.ajax()zamiast $.ajax()pomimo:

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

0

Jest to również przyczyna: jeśli zbudowałeś kolekcję jQuery (przez .map () lub coś podobnego), nie powinieneś używać tej kolekcji w danych .ajax (). Ponieważ nadal jest to obiekt jQuery , a nie zwykły JavaScript Array . Powinieneś użyć .get () na i, aby uzyskać zwykłą tablicę js i powinieneś użyć jej w ustawieniach danych w .ajax ().

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.