JQuery: 'Uncaught TypeError: Незаконне виклик' на запит ajax - кілька елементів


112

У мене є два елементи вибору, A і B: коли вибраний варіант A змінюється, параметри B повинні бути оновлені відповідно. Кожен елемент A передбачає багато елементів у B, це відносини один до багатьох (A містить нації, B має містити міста, розташовані в даній нації).

Функція do_ajaxповинна запускати асинхронний запит:

function do_ajax(elem, mydata, filename)
{
    $.ajax({
        url: filename,
        context: elem,
        data: mydata,
        datatype: "html",
        success: function (data, textStatus, xhr) {
            elem.innerHTML = data;
        }
    });
}

Щоб оновити параметри B, я додав виклик функції в onChangeподії A. Ось функція, яка запускається при запуску onChange події (з A):

function my_onchange(e) // "e" is element "A"
{
    var sel_B = ... ; // get select element "B"

    // I skipped some code here
    // ...

    var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
    };
    do_ajax(city_sel, data, 'ajax_handler.php');
}

}

Я читав у документах JQuery, які dataможуть бути масивом (парами ключових значень). Я отримую помилку, якщо ставлю:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
};

Натомість я не отримую цієї помилки, якщо мої дані є рядком:

var data = 'mode=filter_city&id_A=' + e[e.selectedIndex];

Але мені потрібна "версія масиву" змінної в моєму сервері на PHP-коді.

Uncaught TypeError: Illegal invocationЗнаходиться в файлі «JQuery-1.7.2.min.js», який все стискається, так що я не міг зрозуміти, яка частина коду підняв помилку.

Чи можу я змінити свій код у своєму коді, щоб він приймав дані як асоціативний масив?

Відповіді:


151

Завдяки розмові з Сарфраз ми могли знайти рішення.

Проблема полягала в тому, що я передавав HTML-елемент замість його значення, що насправді те, що я хотів зробити (адже в моєму PHP-коді мені потрібно це значення як зовнішній ключ для запиту моєї citiesтаблиці та фільтрації правильних записів).

Отже, замість:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
};

вона повинна бути:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex].value
};

Примітка: перевірити Джейсон Kulatunga в відповідь , він цитує JQuery документ , щоб пояснити , чому пропускання HTML елемент є причиною неприємностей.


саме те, що я робив. Забув користуватися .val ()
Usman Shaukat

Я передавав опцію, елемента виділення html у змінній. Не помітив, що це не звичайний текст, а html.
Стерлінг Діаз

46

З документів jQuery для processData:

processData Boolean
За замовчуванням: true
За замовчуванням дані, передані в параметр даних як об’єкт (технічно що-небудь, крім рядка), будуть оброблені та перетворені в рядок запиту, що відповідає стандартному вмісту типу "application / x-www -форма-урленкодований ". Якщо ви хочете надіслати документ DOMDocument або інші неопрацьовані дані, встановіть цей параметр на значення false.

Джерело: http://api.jquery.com/jquery.ajax

Схоже, вам доведеться використовувати processDataдля надсилання своїх даних на сервер або змінити ваш скрипт php для підтримки параметрів закодованих запитів.


1
Це правда. Якби я міг бачити це раніше, це вказувало б на фактичну помилку в моєму коді. Дякую, я додам у відповідь замітку.
Надір Сампаоолі

25

Я отримував цю помилку під час публікації об’єкта FormData, оскільки я неправильно налаштував виклик ajax. Налаштування нижче вирішили мою проблему.

var myformData = new FormData();        
myformData.append('leadid', $("#leadid").val());
myformData.append('date', $(this).val());
myformData.append('time', $(e.target).prev().val());

$.ajax({
    method: 'post',
    processData: false,
    contentType: false,
    cache: false,
    data: myformData,
    enctype: 'multipart/form-data',
    url: 'include/ajax.php',
    success: function (response) {
        $("#subform").html(response).delay(4000).hide(1); 
    }
});

дякую людині. u врятував мій день, і мою проблему вирішено додаванням "bodyData: false, contentType: false, cache: false" в моє тіло ajax. Дуже дякую.
CumaTekin

11

Я читав в документах JQuery, що дані можуть бути масивом (парами ключових значень). Я отримую помилку, якщо ставлю:

Це об'єкт не масив:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
};

Ви, мабуть, хочете:

var data = [{
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
}];

1
вона більше не кидає цю помилку, але, схоже, ці дані не передаються моєму $_GETсервісу масиву ( var_export($_GET)виходи array ( 'undefined' => 'undefined', ))
Nadir Sampaoli

@nadirs: Спробуйте визначити тип методу у своєму $.ajaxобробнику:type:'get',
Сарфраз

@Sarfraz результат той самий. На стороні сервера, dataключі повинні знаходитись у масиві GET, правда? Чи, можливо, їх надіслали іншим способом запиту?
Надір Сампаоолі

@nadirs: Щось подібне спрацьовує data: {foo:'myfoo', bar:'mybar'}, можливо, є якась інша проблема.
Сарфраз

@Sarfraz Я ідіот, я надсилав HTML-об’єкт, e[e.selectedIndex]тоді як я повинен був передати його значення e[e.selectedIndex].value. Після виправлення цього недоліку позначення об'єкта справно працює.
Надір Сампаоолі

7

Було те саме питання нещодавно, вирішене додаванням traditional: true,


Це насправді працює, але я припускаю, що для сучасних браузерів
barnacle.m

0
function do_ajax(elem, mydata, filename)
{
    $.ajax({
        url: filename,
        context: elem,
        data: mydata,
        **contentType: false,
        processData: false**
        datatype: "html",
        success: function (data, textStatus, xhr) {
            elem.innerHTML = data;
        }
    });
}

4
Хороший відповідь більше , ніж просто фрагмент коду. Слід пояснити, чому це дає відповідь на початкове запитання, та надавати посилання на відповідну документацію, якщо вона є.
JSTL

Без двох полів contentTypeі processData, помилка продовжуватиме відображатися. Я додав два поля, і це працювало на мене. Я думаю, що ОП намагався вказати два важливі сфери.
Ekundayo Blessing Funminiyi

-1
$.ajax({
                    url:"",
                    type: "POST",
                    data: new FormData($('#uploadDatabaseForm')[0]),
                    contentType:false,
                    cache: false,
                    processData:false,
                    success:function (msg) {}
                  });

7
Відповіді корисніші, якщо включити пояснення.
Джон Б

-2

Спробуйте це:

            $.ajax({
                    url:"",
                    type: "POST",
                    data: new FormData($('#uploadDatabaseForm')[0]),
                    contentType:false,
                    cache: false,
                    processData:false,
                    success:function (msg) {}
                  });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.