Как отправить 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[]: [], вероятно, из-за ограничений строки запроса.

Redsandro
источник
7
Это не dataTypeимеет никакого отношения к тому, как данные отправляются. Он просто указывает , что тип данных вы ожидаете, что возвращается при вызове. Если вы хотите указать серверу, какой тип данных вы указываете в dataсвойстве, вам нужно установить contentTypeсвойство, аналогичноеcontentType: "application/json"
Nope
Спасибо за разъяснение. Но в таком случае зачем мне указывать тип ответа на стороне клиента, если сервер предоставляет в ответе заголовок типа контента?
Redsandro
2
Вам не нужно указывать его, по умолчанию jQuery попытается сделать интеллектуальное предположение на основе MIME-типа ответа. Однако, указав его, вы явно указываете jQuery, какой тип вы ожидаете от сервера, и jQuery попытается преобразовать ответ в объект этого типа. Если вы не укажете его и оставите jQuery без ответа, это может привести к тому, что jQuery преобразует ответ в неожиданный формат, даже если вы отправили JSON с сервера. Проверьте документацию для получения более подробной информации о dataType: api.jquery.com/jQuery.ajax
Нет
Возможный дубликат Jquery Ajax Отправка json на веб-сервис
Мадура Прадип

Ответы:

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 .

mekwall
источник
14
Это не сработает, ты пропал contentType: 'application/json'.
Ohgodwhy
@ Ohhodwhy О, да. Это произошло слишком быстро;)
mekwall,
1
Спасибо. Я думал, что dataType позаботился об этом, но я понял это задом наперед. Какие-нибудь мысли об указании кодировки в типе контента, как Берги в другом ответе?
Redsandro
5
@Redsandro Это не должно быть необходимым. Согласно документам jQuery:POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard
Мекволл
1
@ shortif2000 лучше поздно, чем никогда ... проблема в том, что в $_POSTphp вы можете видеть только application/x-www-form-urlencoded, если вы хотите прочитать данные json, которые вы должны сделать, file_get_contents("php://input")и, возможно, затемjson_decode()
santiago arizti
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его, в него не включен ни один строковый преобразователь; вам понадобится еще одна библиотека polyfill.

Берги
источник
4
Установка processDataв falseне обязательна, так как JSON.stringifyуже возвращает строку.
Мекволл
@MarcusEkwall: Afaik это все еще будет Эд encodeURIComponent, не так ли?
Берги
Хорошо, это может не понадобиться, но вы действительно думаете, что это приведет к сбою запроса?
Берги
Это не должно вызывать сбои, учитывая, что это уже строка.
Кевин Б.
1
@Redsandro: Да, он делает "интеллектуальное предположение". Однако причина этого параметра заключается не только в том, что люди хотят сделать его строгим, но и в том, что они не устанавливают соответствующие типы MIME в своих ответах сервера.
Берги
5

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

Поскольку мои http-запросы обрабатываются CGI API от IBM (среда AS400) на другом поддомене, эти запросы имеют перекрестное происхождение, отсюда и jsonp. Я фактически отправляю свой ajax через объект (ы) javascript. Вот пример моего ajax POST:

 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
       });
yardpenalty.com
источник
2
Спасибо за добавление знаний к этому вопросу! Удовлетворительный ответ уже был дан, но я проголосовал за ваш.
Redsandro
1

Если вы отправляете это обратно на asp.net и вам нужны данные в request.form [], тогда вам нужно установить тип контента «application / x-www-form-urlencoded; charset = utf-8»

Оригинальный пост здесь

Во-вторых, избавьтесь от Datatype, если вы не ожидаете возврата, POST будет ждать около 4 минут, прежде чем потерпит неудачу. Смотри здесь

пройдоха
источник