如何使用 $.ajax 发送 JSON 而不是查询字符串?

Posted

技术标签:

【中文标题】如何使用 $.ajax 发送 JSON 而不是查询字符串?【英文标题】:How to send JSON instead of a query string with $.ajax? 【发布时间】:2012-09-23 12:32:18 【问题描述】:

有人可以简单地解释一下如何让 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[]: [],这可能是由于查询字符串的限制。

【问题讨论】:

dataType 与数据的发送方式无关。它仅指定您希望调用返回的数据类型。如果您想向服务器指示您在data 属性中指定的数据类型,您需要设置类似于contentType: "application/json"contentType 属性 感谢您的澄清。但是在那种情况下,如果服务器在响应中提供了 content-type 标头,为什么我需要在客户端指定响应类型呢? 你没有来指定它,默认情况下jQuery会尝试根据响应的MIME类型进行智能猜测。但是,通过指定它,您将明确告诉 jQuery 您希望从服务器获得什么类型,并且 jQuery 将尝试将响应转换为该类型的对象。不指定它并让 jQuery 进行猜测可能会导致 jQuery 将响应转换为意外格式,即使您从服务器发送了 JSON。查看文档以获取有关数据类型的更多详细信息:api.jquery.com/jQuery.ajax Jquery Ajax Posting json to webservice的可能重复 【参考方案1】:

您需要先使用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。

【讨论】:

这行不通,你错过了contentType: 'application/json' @Ohgodwhy 哦,是的。这有点太快了;) 谢谢。我以为 dataType 会解决这个问题,但我倒退了。对像 Bergi 在其他答案中所做的那样在内容类型中指定字符集有什么想法吗? @Redsandro 这不应该是必要的。根据 jQuery 文档:POST data will always be transmitted to the server using UTF-8 charset, per the W3C XMLHTTPRequest standard @shorif2000 迟到总比没有好...问题是在$_POSTphp 中你只能看到application/x-www-form-urlencoded,如果你想读取json 数据你必须做file_get_contents("php://input") 并且也许然后是json_decode()【参考方案2】:

不,dataType option 用于解析接收到的数据。

要发布 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 库。

【讨论】:

没有必要将processData 设置为false,因为JSON.stringify 已经返回了一个字符串。 @MarcusEkwall:Afaik 仍然是encodeURIComponented,不是吗? 好的,它可能不需要,但你真的认为它会使请求失败吗? 它不应该让它失败,考虑到它已经是一个字符串。 @Redsandro:是的,它正在做一个“智能猜测”。但是,该参数的原因不仅仅是(仅)人们想要使其严格,更多的是他们没有在服务器响应中设置适当的 MIME 类型。【参考方案3】:

虽然我知道像 ASP.NET MVC 这样的许多架构都有内置功能来处理 JSON.stringify 作为 contentType,但我的情况有点不同,所以这可能对将来的某人有所帮助。我知道这会节省我几个小时!

由于我的 http 请求是由来自 IBM(AS400 环境)的 CGI API 在不同子域上处理的,因此这些请求是跨源的,因此是 jsonp.我实际上是通过 javascript 对象发送我的 ajax。这是我的 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
       );

【讨论】:

感谢您为这个问题添加更多知识!令人满意的答案已经给出,但我赞成你的。【参考方案4】:

如果您将其发送回 asp.net 并需要 request.form[] 中的数据,那么您需要将内容类型设置为“application/x-www-form-urlencoded; charset=utf-8 "

原帖here

其次摆脱数据类型,如果您不期望返回,则 POST 将在失败前等待大约 4 分钟。见here

【讨论】:

以上是关于如何使用 $.ajax 发送 JSON 而不是查询字符串?的主要内容,如果未能解决你的问题,请参考以下文章

Yii2网格视图使用ajax而不是Pjax进行过滤

Select2 小部件将 param.term 空格作为“+”而不是 %20 发送到 ajax

如何仅获取阴影属性而不是基本属性来获取 JSON 序列化?

Django:使用 ajax 查询(字符串/Json)时出现格式问题

Ajax 的跨域限制 - JSON

AJAX如何解析后台传来的json数据?