jQuery: invocación ilegal

108

jQuery v1.7.2

Tengo esta función que me está dando el siguiente error al ejecutar:

Uncaught TypeError: Illegal invocation

Esta es la función:

$('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 dataelimino de la llamada ajax, funciona ... ¿alguna sugerencia?

¡Gracias!

yoda
fuente
intente eliminar fromde los datos. Tal vez esté en conflicto con jquery de
gopi1410
6
Te das cuenta de que estás intentando empujar objetos jQuery, no JSON, ¿verdad?
asawyer
18
Me sucede regularmente cuando olvido el .val () en algún objeto jQuery ...
userfuser

Respuestas:

118

Creo que necesitas tener cadenas como valores de datos. Es probable que sea algo interno dentro de jQuery que no esté codificando / serializando correctamente los objetos hacia y desde.

Tratar:

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

Note también en las líneas:

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

No necesita el contenedor jQuery ya que To & From ya son objetos jQuery.

LessQuesar
fuente
2
Gracias, olvidé que había cargado objetos en lugar de cadenas, generalmente cargo cadenas :)
yoda
3
Este enfoque me ayuda. Nombro mis variables como $from = $('#from');Esto me ayuda a recordar que representa un objeto jQuery que ayuda a evitar llamar a un método en algo que es una cadena o intentar manipular una cadena .toString()o algo cuando es un objeto jQuery.
timbrown
Me .val()faltaba la pieza, por lo que no estaba pasando el valor.
SharpC
109

Intente establecer processData: false en configuraciones de ajax como esta

$.ajax({
    url : base_url+'index.php',
    type: 'POST',
    dataType: 'json',
    data: data,
    cache : false,
    processData: false
}).done(function(response) {
    alert(response);
});
Justo
fuente
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.
Es posible que también deba agregar contentType: false. Lo hice al subir un archivo. Ver stackoverflow.com/questions/21044798/…
khylo
18

Solo para el registro, también puede suceder si intenta utilizar una variable no declarada en datos como

var layout = {};
$.ajax({
  ...
  data: {
    layout: laoyut // notice misspelled variable name
  },
  ...
});
Ivan Ivanić
fuente
1
¡¡Gracias por eso!! Eso fue totalmente donde me bloquearon.
Matt Zelenak
13

Si desea enviar un formulario utilizando Javascript FormData API con la carga de archivos, debe establecer dos opciones a continuación:

processData: false,
contentType: false

Puede intentar lo siguiente:

//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
fuente
¿Qué hacen estas dos opciones, podría explicarlo?
rahim.nagori
2

En mi caso, acabo de cambiar

Nota: Esto es en el caso de Django, así que agregué csrftoken. En su caso, es posible que no lo necesite.

Agregado contentType: false,processData: false

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

    }
})

a

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

    }
})

Y funcionó.

higull
fuente
2

En mi caso, no he definido todas las variables que paso a los datos en ajax.

var page = 1;

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

Acabo de definir la variable var search_candidate = "candidate name";y su funcionamiento.

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
fuente
0

Mi problema no estaba relacionado con processData. Fue porque envié una función que no se puede llamar más tarde applyporque no tenía suficientes argumentos. Específicamente, no debería haberlo usado alertcomo errordevolución de llamada.

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

Consulte esta respuesta para obtener más información sobre por qué eso puede ser un problema: ¿Por qué ciertas llamadas a funciones se denominan "invocaciones ilegales" en JavaScript?

La forma en que pude descubrir esto fue agregando un console.log(list[ firingIndex ])a jQuery para poder rastrear lo que estaba disparando.

Esta fue la solución:

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
fuente
0

En mi caso (usando webpack 4) dentro de una función anónima, que estaba usando como devolución de llamada.

Tuve que usar en window.$.ajax()lugar de a $.ajax()pesar de tener:

import $ from 'jquery';
window.$ = window.jQuery = $;
guerra zander
fuente
0

Además, esto también es una causa: si creó una colección jQuery (a través de .map () o algo similar), entonces no debería usar esta colección en los datos de .ajax (). Porque sigue siendo un objeto jQuery , no una matriz JavaScript simple . Debe usar .get () en y para obtener una matriz js simple y debe usarlo en la configuración de datos en .ajax ().

Burak TARHANLI
fuente