JSON:未捕获的语法错误:意外的标记“:”

69

尝试进行调用并检索一个非常简单的、只有一行的JSON文件。

$(document).ready(function() {

    jQuery.ajax({ 
        type: 'GET',
        url: 'http://wncrunners.com/admin/colors.json' ,
        dataType: 'jsonp', 
        success: function(data) { 
            alert('success');
        }
    });


  });//end document.ready

以下是原始请求:

GET http://wncrunners.com/admin/colors.json?callback=jQuery16406345664265099913_1319854793396&_=1319854793399 HTTP/1.1
Host: wncrunners.com
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.106 Safari/535.2
Accept: */*
Referer: http://localhost:8888/jquery/Test.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

以下是原始响应内容:

HTTP/1.1 200 OK
Date: Sat, 29 Oct 2011 02:21:24 GMT
Server: Apache/1.3.33 (Unix) mod_ssl/2.8.22 OpenSSL/0.9.7d SE/0.5.3
Last-Modified: Fri, 28 Oct 2011 17:48:47 GMT
ETag: "166a2402-10-4eaaeaff"
Accept-Ranges: bytes
Content-Length: 16
Content-Type: text/plain
Connection: close

{"red" : "#f00"}

响应中返回了JSON (红色: #f00),但Chrome报告了Uncaught SyntaxError: Unexpected token : colors.json:1

如果我直接导航到URL本身,JSON将会被返回并在浏览器中显示。

如果我将colors.json的内容粘贴到JSLINT中,JSON将会验证通过。

有什么想法为什么我不能得到这个错误,并且我从来没有进入过成功回调?

EDIT - 上面的jQuery.ajax()调用在jsfiddle.net上运行得很好,并返回预期的警报“success”。

EDIT 2 - 此URL正常工作'http://api.wunderground.com/api/8ac447ee36aa2505/geolookup/conditions/q/IA/Cedar_Rapids.json' ,我注意到它返回为TYPE:text/javascript,而Chrome没有抛出Unexpected Token。 我测试了几个其他URL,唯一不抛出Unexptected Token的是以TYPE:text/javascript返回的wunderground。

返回为text/plain和application/json的流没有正确解析。


顺便提一下,我发现在浏览器中访问该URL时,"#"实际上不会显示在JSON中。 http://wncrunners.com/admin/colors.json - nheinrich
感谢您的输入。我已经移除了#来测试Keith的理论。然而,移除它并没有影响到错误。我还将文件中的.json扩展名移除了,但是仍然出现同样的错误。 - paparush
4个回答

130
你告诉了jQuery期望JSONP响应,这就是为什么jQuery添加了callback=jQuery16406345664265099913_1319854793396&_=1319854793399部分到URL中(你可以在请求的转储中看到这个)。
你返回的是JSON而不是JSONP。你的响应看起来像是:
{"red" : "#f00"}

而jQuery期望的是这样的内容:

jQuery16406345664265099913_1319854793396({"red" : "#f00"})

如果您需要使用JSONP来绕过同源策略,那么提供colors.json的服务器需要能够实际返回JSONP响应。
如果同源策略对您的应用程序没有影响,则只需将jQuery.ajax调用中的dataType修正为json而不是jsonp即可。

好的。你给出的Weather Underground URL确实可以响应JSONP请求。(如果你在URL后面添加?callback=something,你就会看到这一点。当你使用dataType: json时出现错误是因为同源策略。让我对我的回答进行补充。 - John Flatness
问题似乎是如果服务器响应类型为text/javascript,则Chrome不会报告Uncaught SyntaxError。 如果远程服务器返回类型为text/plain或application/json,则Chrome报告Uncaught SyntaxError。 - paparush
@JohnFlatness 感谢您的解释,我遇到了同样的问题,但我无法更改我的服务器代码,我必须在客户端调用上进行操作。有什么建议或JS可以帮助解决这个问题?如果不使用JSONP,就会出现跨域错误,因此需要使用JSONP。这是我的问题的fiddle链接:http://jsfiddle.net/waamit14/wZSeB/ - Amit Rana

4
我已经花了几天时间尝试自己解决这个问题。使用旧的json dataType会导致跨域问题,而将dataType设置为jsonp会使数据变得“不可读”,如上所述。因此,有两种方法可以解决问题,第一种对我来说没有用,但似乎是一个潜在的解决方案,我可能做错了什么。这在这里解释 [ https://learn.jquery.com/ajax/working-with-jsonp/ ]。
我用的是以下方法: 1- 下载ajax跨域插件 [ http://www.ajax-cross-origin.com/ ]。 2- 在普通的jQuery链接下添加脚本链接。 3- 在你的ajax函数中添加"crossOrigin: true,"这一行。
就这样!以下是我的可运行代码:

  $.ajax({
      crossOrigin: true,
      url : "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.86,151.195&radius=5000&type=ATM&keyword=ATM&key=MyKey",
      type : "GET",
      success:function(data){
         console.log(data);
      }
    })


1
一个快速提醒:那个ajax跨域插件使用了谷歌代理。所以你所做的就是将你的数据传输到别人为你编写的代理服务器上。 - user4593252

2
我曾经遇到过同样的问题,解决方法是将json封装在以下函数中:
jsonp(
....你的json...
)

6
你是否在服务器端进行封装?或者有没有办法在客户端完成这个任务? - Fydo

1

那个十六进制数可能需要用引号括起来并转换为字符串。Javascript 可能不喜欢 # 字符。


Keith,感谢您的回复。为了测试,我从文件中删除了#号,使得内容现在是{"red" : "f00"},但是仍然出现相同的错误。我注意到的一件事是响应Content-Type是text/plain而不是application/json。 - paparush
作为另一个测试,我将文件重命名为仅为“colors”(没有扩展名),但我收到了完全相同的错误。 - paparush

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接