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.