jQuery - 消耗JSON资源 - 一些返回数据,另一些则没有。为什么?

时间:2010-06-18 19:59:07

标签: jquery ajax json jsonp

我正在试图弄清楚如何在浏览器中使用json URL并使用DOM在我的网页中呈现数据。我没有得到一致或可预测的回应。

我找到了一个JSON URL at Google Calendar,如果我只是在地址栏中输入网址,我会在浏览器中显示json响应。

如果我只是在地址栏中输入网址,我发现另一个JSON URL at business.gov在我的浏览器中显示了不同的json响应。 。

然后我尝试使用jQuery发出$ .ajax调用来使用和显示这两种JSON资源。

<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
  htmlobj=$.ajax(
            {url:"http://www.google.com/calendar/feeds/developer-calendar@google.com/public/full?alt=json",
             async:false} 
            );

  if (jQuery.isEmptyObject(htmlobj.responseText)===true) {
    alert("htmlobj.responseText is empty");
  } else {
    alert("htmlobj.responseText has stuff in it");
  }

  $("#myDiv").html(htmlobj.responseText).fadeIn();

  htmlobj1=$.ajax(
         {url:"http://api.business.gov/geodata/city_county_links_for_state_of/CA.json",
                async:false, 
                dataType:'text', 
                });

  if (jQuery.isEmptyObject(htmlobj1.responseText)===true) {
    alert("htmlobj1.responseText is empty");
  } else {
    alert("htmlobj1.responseText has stuff in it");
  }

  $("#myGovDiv").html(htmlobj1.responseText).fadeIn();
});
</script>
</head>
<body>
   <h3>Google Calendar - json only</h3>
   <div id="myDiv" style="display:none"></div>

   <h3>Business.Gov</h3>
   <div id="myGovDiv" style="display:none"></div>
</body>

Google Calendar JSON资源已正常使用,但business.gov JSON资源甚至没有回复到响应中。 (我使用Firebug进行了检查,它在响应文本中没有返回HTTP代码200)。

两个JSON URL如何在浏览器中返回良好的JSON数据,但jQuery.ajax只能使用Google Calendar URL,而jquery.ajax无法使用business.gov URL?

编辑 - 2010年6月19日,美国东部时间6:36 - 感谢@Juan Manuel@TheJuice。我试过jsonp ......这就是我得到的。

如果我将调用更改为以下内容,我可以让浏览器停止阻止来自api.business.gov的响应,但我无法获取数据(例如htmlobj2是零)

  htmlobj2=$.ajax(
        {url:"http://api.business.gov/geodata/city_county_links_for_state_of/CA.json",
         async: false,
         dataType: 'jsonp',
         success: function(data, textStatus) {
            alert("Success");
            $('#myDiv').html("Your data: " );
       },
         error: function ( XMLHttpRequest, textStatus, errorThrown){
                    alert('error');
                }
    }
);

无论我使用'jsonp'或'script'的dataType,我都得到相同的结果。 htmlobj2为nil,但响应头包含整个json数据字符串。此外,如果我尝试将回调函数绑定到带有“data”作为参数的.ajax调用,那么“data”参数也是一个nil对象。此外,成功或失败处理程序都不会被调用。

如何从响应字符串中提取此JSON数据并将其显示在我的网页上?

编辑 - 2010年6月22日,上午11:17

我找到了一个Ruby脚本并调整它以尝试使用URL。我用交互式Ruby(irb)运行它。

require 'rubygems'
require 'json'
require 'net/http'

url = "http://api.business.gov/geodata/city_county_links_for_state_of/CA.json"
resp = Net::HTTP.get_response(URI.parse(url))
data = resp.body
result = JSON.parse(data)
result.each{|entry| p entry["name"] + "," + entry["full_county_name"] }

我也可以使用类似的Ruby脚本来使用Google Calendar URL。

底线?我能够使用Ruby来使用JSON资源(api.business.gov和Google Calendar),但只能使用浏览器中使用Javascript / jQuery的Google Calendar资源。

我很欣赏我能得到的任何见解。从网络上的任何文档或API描述中都可以看出,无论如何,Google日历Feed都在浏览器中工作,但api.business.gov提要在使用JSON或JSONP的浏览器中不起作用。

3 个答案:

答案 0 :(得分:4)

正如Juan Manuel所指出的,这是您的浏览器保护您免受跨站脚本攻击。如果您在Fiddler中查看您的请求,您可以看到发生了什么。

这是谷歌响应标题的一部分:

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Access-Control-Allow-Origin: *
Rest Omitted...

这是来自business.gov:

HTTP/1.1 200 OK
Date: Fri, 18 Jun 2010 21:52:10 GMT
Server: Mongrel 1.1.4
Status: 200 OK
X-Runtime: 0.36775
ETag: "172ec84fa79f748265e96d467af3d3dd"
Cache-Control: private, max-age=0, must-revalidate
Content-Type: application/json; charset=utf-8
Via: 1.1 api.business.gov
Content-Length: 229427
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
Set-Cookie: .....7c5; path=/
Age: 0

[
  {"name": "Adelanto" ,
   "fips_county_cd": "71" ,
   "feat_class": "Populated Place" ,
   "county_name": "San Bernardino" ,
   "primary_latitude": "34.58" ,
   "state_name": "California" ,
..... (rest omited)

您看到来自business.gov的回复实际上已被退回,但被浏览器屏蔽了。

更新更新: Google Web服务正在为您处理JSONP以及jQuery。 business.gov Web服务显然不支持JSONP。您将需要使用Ruby(服务器端代码)充当代理并使用business.gov服务,然后将响应返回给客户端。

答案 1 :(得分:2)

same origin policy

可能存在问题

您可以尝试使用JSONP吗? 我有同样的问题(firebug显示空数据)并用它解决了它,但我控制了Web服务并可以修改它以支持它。

答案 2 :(得分:1)

两者之间的一个区别是服务器报告结果的Content-Type

Fiddler将Google日历调用显示为Content-Type: text/plain; charset=UTF-8,而business.gov 未指定Content-Type application/json; charset=utf-8(已编辑,我的初步答案)来自缓存的回复)。

Content-Type基本上告诉浏览器响应的文件类型 - 它与Windows中的文件扩展名非常相似。它也被称为MIME类型,并且具有一些相当深远的影响(例如,它优先于HTML / XHTML文件中的DTD - 因此,如果您使用text / html Content-Type提供XHTML,那么浏览器实际上会将响应视为HTML - ,因此许多声称符合XHTML标准的网站实际上都在提供无效的HTML


TheJuice似乎在Fiddler中看到了不同的结果,所以为了比较,这里是我在测试中看到的标题:

Google日历

HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Expires: Tue, 22 Jun 2010 15:25:41 GMT
Date: Tue, 22 Jun 2010 15:25:41 GMT
Cache-Control: private, max-age=0, must-revalidate, no-transform
Vary: Accept, X-GData-Authorization, GData-Version
GData-Version: 1.0
Last-Modified: Tue, 22 Jun 2010 12:19:15 GMT
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Content-Length: 49803

Business.gov:

HTTP/1.1 200 OK
Date: Tue, 22 Jun 2010 15:34:33 GMT
Server: Mongrel 1.1.4
Status: 200 OK
X-Runtime: 0.37833
ETag: "172ec84fa79f748265e96d467af3d3dd"
Cache-Control: private, max-age=0, must-revalidate
Content-Type: application/json; charset=utf-8
Content-Length: 229427
Via: 1.1 api.business.gov
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive