Як надіслати 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.