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

时间:2011-04-18 19:06:47

标签: javascript jquery ajax json

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

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

问题可以在Firefox 4和Chrome 10中重现。您需要控制台才能看到正在发生的事情。

以下是代码:

<?
$input = file_get_contents('php://input');
if (isset($input) and !empty($input)) {
    echo $input;
    die();
}

?>

<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
        <script>
            $(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);
            });
        </script>
    </head>
    <body>
        <pre>Check your JavaScript console...</pre>
    </body>
</html>

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

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

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

如果你注释掉“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"}

8 个答案:

答案 0 :(得分:18)

使用??时,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 CHANGED THE POST CONTENT IF INCLUDE "??" (2 QUESTION MARK)

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

答案 1 :(得分:5)

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

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

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

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

答案 2 :(得分:2)

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

能够通过删除

来修复它
dataType: 'JSON'

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

答案 3 :(得分:2)

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

阅读此类似问题的答案以获取更多详细信息: Post data being overriden since upgrading from jQuery 1.4 to 1.5

答案 4 :(得分:1)

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

答案 5 :(得分:1)

我在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 ) ) ) {

我采用了jQuery 1.6.4的修复形式。

答案 6 :(得分:1)

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

答案 7 :(得分:1)

我遇到了同样的问题。指定“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) {

    }
});