Як надіслати JSON замість рядка запиту з $ .ajax?


172

Чи може хтось легко пояснити, як змусити jQuery надсилати фактичний JSON замість рядка запиту?

$.ajax({
    url      : url,
    dataType : 'json', // I was pretty sure this would do the trick
    data     : data,
    type     : 'POST',
    complete : callback // etc
});

Це фактично перетворить ваш ретельно підготовлений JSON в рядок запиту. Одне з дратівливих речей полягає в тому, що будь-який array: []предмет у вашому об’єкті буде перетворений array[]: [], ймовірно, через обмеження місця запиту.


7
Це dataTypeне стосується того, як дані надсилаються. Він лише вказує, який тип даних, як ви очікуєте, буде повернутий дзвінком. Якщо ви хочете вказати серверу, який тип даних, ви вказуєте у dataвластивості, вам потрібно встановити contentTypeвластивість, аналогічнуcontentType: "application/json"
Nope

Дякуємо за уточнення. Але в такому випадку, чому мені потрібно вказати тип відповіді на стороні клієнта, якщо сервер надає заголовок типу вмісту у відповіді?
Редсандро

2
Не потрібно його вказувати, за замовчуванням jQuery спробує зробити інтелектуальну здогадку на основі типу відповіді MIME. Однак, вказавши його, ви чітко повідомляєте jQuery, який тип ви очікуєте від сервера, а jQuery намагатиметься перетворити відповідь на об’єкт цього типу. Якщо його не вказати і не залишити здогадку jQuery, це може призвести до перетворення jQuery відповіді у несподіваний формат, навіть якщо ви надіслали JSON з сервера. Перегляньте документацію для отримання більш детальної інформації про тип даних: api.jquery.com/jQuery.ajax
Nope

Відповіді:


256

Вам потрібно JSON.stringifyспочатку серіалізувати ваш об’єкт до JSON, а потім вказати contentTypeтак, щоб ваш сервер розумів, що це JSON. Для цього слід зробити фокус:

$.ajax({
    url: url,
    type: "POST",
    data: JSON.stringify(data),
    contentType: "application/json",
    complete: callback
});

Зауважте, що JSONоб'єкт доступний у веб-переглядачах, які підтримують JavaScript 1.7 / ECMAScript 5 або новішої версії. Якщо вам потрібна застаріла підтримка, ви можете використовувати json2 .


14
Це не вийде, ви пропускаєте contentType: 'application/json'.
Ohgodwhy

@ Ohgodwhy О так. Це пішло занадто швидко;)
mekwall

1
Дякую. Я думав, що dataType подбав про це, але я зрозумів це назад. Будь-які думки щодо того, щоб вказати схему для типу вмісту, як Бергі, робив в іншій відповіді?
Редсандро

5
@Redsandro Це не повинно бути необхідним. Згідно з документами jQuery:POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard
mekwall

1
@ shorif2000 краще пізніше, ніж ніколи ... проблема полягає в тому, що в $_POSTphp ви бачите лише application/x-www-form-urlencoded, якщо хочете прочитати дані json, що вам потрібно зробити, file_get_contents("php://input")і, можливо, тодіjson_decode()
Сантьяго Арісті

28

Ні, dataTypeопція полягає в аналізі отриманих даних.

Щоб опублікувати JSON, вам потрібно буде самостійно впорядкувати його JSON.stringifyі встановити processDataпараметр на false.

$.ajax({
    url: url,
    type: "POST",
    data: JSON.stringify(data),
    processData: false,
    contentType: "application/json; charset=UTF-8",
    complete: callback
});

Зауважте, що не всі веб-переглядачі підтримують JSONоб’єкт, і хоча у jQuery є .parseJSON, він не включає в себе стрифікатор; вам знадобиться ще одна бібліотека для заповнення полів.


4
Установка processDataдля falseне потрібно , так як JSON.stringifyвже повертає рядок.
mekwall

@MarcusEkwall: Афаїк це все одно буде encodeURIComponentредагуватися, чи не так?
Бергі

Гаразд, це може не знадобитися, але ви дійсно думаєте, що це призведе до відмови запиту?
Бергі

Це не повинно робити його невдалим, враховуючи, що це вже рядок.
Кевін Б

1
@Redsandro: Так, це робить "розумний здогад". Однак причина цього параметра полягає не лише в тому, що люди хочуть зробити його суворим, але більше в тому, що вони не встановлюють відповідні типи MIME у відповідях свого сервера.
Бергі

5

Хоча я знаю, що багато архітектур, таких як ASP.NET MVC, мають вбудовану функціональність для обробки JSON.stringify як contentType, моя ситуація дещо інша, тому, можливо, це може допомогти комусь у майбутньому. Я знаю, що це врятувало б мені години!

Оскільки мої запити http обробляються API CGI від IBM (середовище AS400) в іншому субдомені, ці запити мають поперечне походження, отже, і jsonp. Я фактично надсилаю свій ajax через javascript-об’єкти. Ось приклад моєї поштової пошти Ajax:

 var data = {USER : localProfile,  
        INSTANCE : "HTHACKNEY",  
        PAGE : $('select[name="PAGE"]').val(), 
        TITLE : $("input[name='TITLE']").val(), 
        HTML : html,
        STARTDATE : $("input[name='STARTDATE']").val(), 
        ENDDATE : $("input[name='ENDDATE']").val(),
        ARCHIVE : $("input[name='ARCHIVE']").val(), 
        ACTIVE : $("input[name='ACTIVE']").val(), 
        URGENT : $("input[name='URGENT']").val(), 
        AUTHLST :  authStr};
        //console.log(data);
       $.ajax({
            type: "POST",
           url:   "http://www.domian.com/webservicepgm?callback=?",
           data:  data,
           dataType:'jsonp'
       }).
       done(function(data){
         //handle data.WHATEVER
       });

2
Дякуємо, що додали більше знань до цього питання! Задовольняюча відповідь вже була дана, але я підтримав вашу.
Редсандро

1

Якщо ви надсилаєте це назад на asp.net і потребуєте даних у request.form [], тоді вам потрібно буде встановити тип вмісту на "application / x-www-form-urlencoded; charset = utf-8"

Оригінальний пост тут

По-друге, позбавтеся від типу даних, якщо ваш не очікує повернення, POST буде чекати близько 4 хвилин, перш ніж вийти з ладу. Дивіться тут

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.