当数据包含连续的问号时,难以理解的jQuery $ .ajax()行为

我希望这很清楚,我已经浪费了很多精力试图解决这个问题,所以我可能没有多少留下来写一个完美的问题。 此外,这可能需要进入一个jQuery错误报告,但我宁愿在这里发布它,因为我是一个相对的JavaScript新手,所以也许我做错了…

我创建了以下代码来重现它。 它使用PHP将收到的数据回显给浏览器,尽管它可以在没有任何PHP的情况下工作。

问题可以在Firefox 4和Chrome 10中重现。您需要控制台才能看到发生了什么。

这是代码:

     $(function(){ var jsonData = { "something":"??" }; jsonData = JSON.stringify(jsonData); var onSuccess = function(data){ console.log("Ajax Success!"); console.log(data); } var onError = function(jqXHR, textStatus, errorThrown){ console.log("Ajax Error: "+textStatus); console.log("More info:"); console.log(errorThrown); console.log(jqXHR); } console.log("Now sending this: "+jsonData+" through Ajax..."); var ajaxCmd = { "url" : "test.php", "dataType": "json", "type" : "POST", "async" : false, "error" : onError, "success" : onSuccess, "data" : jsonData }; $.ajax(ajaxCmd); });    
Check your JavaScript console...

加载时,它会抛出一些明显不相关的解析错误或exception(取决于浏览器)。 应该发送的json是{“something”:“??”}但是如果你在Firebug的网络选项卡(或Chrome等价物)中检查它,你会看到“??” 正在被一些jQuery字符串取代,它看起来像:jQuery152026845051744021475_1303152126170

这就是服务器收到的内容。

只有在发送的JSON对象内的值字段中有两个或多个连续的问号时才会出现此问题,即使其中有其他字母也是如此。 有一个问号似乎有效。 另外,将“dataType”更改为“text”可以解决此问题。 但我需要所有这些function!

如果你注释掉“jsonData = JSON.stringify(jsonData);” 或“$ .ajax(ajaxCmd);” 错误也奇迹般地消失了。

更多信息:

Chrome控制台输出:

 test.php:21Now sending this: {"something":"??"} through Ajax... jquery.min.js:16Uncaught SyntaxError: Unexpected token : test.php:16Ajax Error: parsererror test.php:17More info: test.php:18jQuery15206220591682940722_1303153398797 was not called test.php:19 Object 

Firefox Firebug输出:

 Now sending this: {"something":"??"} through Ajax... Ajax Error: parsererror More info: jQuery15206494160738701454_1303153492631 was not called Object { readyState=4, responseText="{"something":"jQuery152...8701454_1303153492631"}", more...} invalid label {"something":"jQuery15206494160738701454_1303153492631"} 

如果您不打算将“数据”值格式化为有效的HTML查询字符串,则不应对其进行预先字符串化。 正如您所指出的,如果您不调用“JSON.stringify()”,那么它可以工作。 那是因为图书馆已经知道为你处理这个问题了。

现在,如果要将JSON字符串作为参数本身发送到需要解码某些JSON的服务器端代码,则需要将其设置为参数:

  $.ajax(url, { // ... data: { jsonParam: jsonData }, // ... }); 

现在,您的服务器将看到一个带有名为“jsonParam”的参数的HTTP请求,其值将是您的JSON字符串字符串。

jQuery使用?? 使用jsonp时作为回调函数的占位符。 当它解析Ajax请求并找到双重问号(或更多问号)时,它会自动假定您正在尝试使用jsonp 。 手动设置内容类型时,它将忽略问号。

因此,使用contentType避免此问题:

 $.ajax( url: "your-url.php", dataType: "json", // what you expect the server to return contentType: "application/json", // what you are sending ... ); 

以供参考:

jQuery Bugtracker:$ .AJAX改变post内容如果包含“??” (2问号)

希望它可以节省其他人的数小时调试…

与jQuery 1.71完全相同的问题,双问号和一些疯狂的字符串被插入。

能够通过删除来解决它

 dataType: 'JSON' 

从ajax命令,它神奇地停止了它。

我认为您正在寻找的答案是在AJAX调用选项中设置jsonp:false。 我有这个完全相同的问题并通过这样做来修复它。

阅读这个类似问题的答案以获取更多详细信息: 从jQuery 1.4升级到1.5后,发布的数据被覆盖

这听起来像编码问题。 如果您的数据不是UTF-8格式(如MS Word或其他),则可能会发生这种情况。

我在1.5.2中遇到了这样的问题。 这是jQuery错误: http : //bugs.jquery.com/ticket/8417 。 您可以更新到1.6.4或者这样做:在jQuery函数“jQuery.ajaxPrefilter”中更改:

 var dataIsString = ( typeof s.data === "string" ); 

通过

 var inspectData = s.contentType === "application/x-www-form-urlencoded" && ( typeof s.data === "string" ); 

并将此变量更改为“if”条件,如下所示:

 if ( s.dataTypes[ 0 ] === "jsonp" || originalSettings.jsonpCallback || originalSettings.jsonp != null || s.jsonp !== false && ( jsre.test( s.url ) || dataIsString && jsre.test( s.data ) ) ) { inspectData && jsre.test( s.data ) ) ) { 

我把这个修复formsjQuery 1.6.4。

我有同样的问题。 使用encodeURIComponent转义值完成了这项工作!

我遇到了同样的问题。 指定“contentType”:“application / json; charset = utf-8”解决了这个问题。

 jQuery.ajax({ "url": url, "data": JSON.stringify(payload), "type": "POST", "dataType": "json", "contentType":"application/json; charset=utf-8", "success": function(data) { }, "error": function(jqXHR, textStatus, errorThrown) { } }); 

由于现有的答案都没有提到这一点。 您可以通过添加来解决此问题

 jsonp: false 

到你的ajax请求设置。