【问题标题】:Acquiring a remote json file获取远程json文件
【发布时间】:2014-02-14 04:17:26
【问题描述】:

我正在学习 JavaScript,但现在我遇到了一个我不理解的问题。此问题与 jQuery.get、CORS、jQuery.getJSON 和 JSONP 有关。

假设我正在编写一个带有一些脚本的 html 文件,该文件正在访问带有一些 JSON 内容的 URL。 html 文件在我的本地文件系统中,如下所示:

<!DOCTYPE html>

<head>
  <title>Test</title>
  <script src = "test.js"
  charset = "UTF-8"></script>
  <script src = "jquery/jquery-1.9.1.js"
  charset = "UTF-8"></script>
</head>

<body>
  <h1>Test</h1>

  <script type="text/javascript">
    queryAuctionFiles('eu', 'tyrande');
  </script>
</body>

body script 标签中调用的函数queryAuctionFiles如下:

// File: test.js
function queryAuctionFiles(realm, server)
{
  var url = 'http://' +
        realm +
        '.battle.net/api/wow/auction/data/' +
        server;

  jQuery.get(url, function(data)
  {
    alert( "Eureka!" );
  });
}

用我的Chrome浏览器(V 32.0.1700.76 m)打开html出现以下错误:

XMLHttpRequest 无法加载 http://eu.battle.net/api/wow/auction/data/tyrande。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问 Origin 'null'。

谷歌搜索我得知这个错误是由于security reasons而禁止从某个域(我的本地文件系统)到另一个域(eu.battle.net)的资源获取。

我也读过这个跨域请求可以用 CORS 来实现,但是如果我没记错的话,这个 CORS 东西必须在请求的两边都启用;就我而言:我的 Chrome 必须支持 CORS,并且 eu.battle.net 必须启用它,我如何才能知道某些域是否支持 CORS?

在为我的问题寻找解决方案时,我发现了jQuery.getJSON方法,所以我尝试了一下,但结果是一样的,代码如下:

jQuery.getJSON(url, function(data)
{
  alert( "Eureka!" );
});

产生相同的 No 'Access-Control-Allow-Origin' 错误,起初,我认为产生错误是因为给定的 url 不是 JSON 文件,但毫无疑问是跨域错误。当我想放弃的时候,我读过 JSONP 以及它是如何被jQuery 管理的:

如果 URL 包含字符串“callback=?” (或类似的,由服务器端 API 定义),请求被视为 JSONP。

所以,我做了以下更改:

jQuery.getJSON(url + '?callback=?', function(data)
{                  //^~~~~~~~~~~~~
  alert( "Eureka!" );
});

然后,我得到一个不同的错误:

Uncaught SyntaxError: Unexpected token :

而且,标记 SyntaxError 的文件名是第 1 行的 tyrande,这个tyrande file 的内容如下所示:

{"files":[{"url":"http://eu.battle.net/auction-data/d5357dc91898b3f78edfd1fbbe8867e8/auctions.json","lastModified":1390475765000}]}

这些内容是我在作为第二个参数传递给 getJSON 的匿名函数中所期望的输入!

getJSON 似乎从提供的 url 下载了一个名为 tyrande 的文件,然后是 eval() 其内容,此内容是 JSON 输入,因此不是有效的 JavaScript 可评估字符串。

现在我已经详细解释了我尝试了什么,并且知道了我的目标,请问:

  • 为了获取远程资源,html 文件是在我的文件系统中还是在远程服务器中很重要?
  • 是否必须启用 CORS?如何在我的脚本上启用它?我必须如何测试远程资源是否支持 CORS?
  • 如果我使用 jQuery.getJSON,资源地址是否不是 JSON 文件很重要?
  • 我在上次更改中做错了什么?为什么下载了一个名为 tyrande 的文件,然后它的内容是 eval()uated?

感谢您的关注

【问题讨论】:

  • 这一切皆有可能,但前提是远程服务器实现了 CORS 或 JSONP。您还可以代理来自您控制的服务器的请求。如果您想了解更多关于这些概念的信息,可以在 SO 上或通过搜索引擎访问这些主题的大量信息。你的情况不是唯一的。它在数百个其他 SO 线程、博客文章和有关跨域通信的文章中都有介绍。
  • 我知道,并且我已经检查了许多 SO 线程,但不幸的是,其中列出的解决方案都不适合我。
  • 您尝试了哪些具体的解决方案?您在问题中缺少此关键组件:服务器端代码。同样,如果您不控制服务器,并且服务器没有实现 JSONP 或 CORS,那么您只能通过您控制的服务器代理请求。
  • 好吧,我不知道如何检查服务器是否允许 CORS(您可以在我的问题列表中看到它);我试图用 jQuery 绕过 Cross Origin(正如我详细描述的那样),现在我被卡住了,我不知道下一步该尝试什么。
  • 您是否尝试过阅读您尝试访问的服务的文档,或者询问维护它的人?除此之外,如果简单的 XHR 请求不起作用,它可能不支持 CORS。如果一个简单的 JSONP 请求不能使用标准回调名称,它可能不支持 JSONP。因此,您需要通过您控制的服务器代理请求。

标签: javascript jquery cors getjson


【解决方案1】:

这是不可能的。跨域策略不允许您从不同域获取文件。

Check this one out

【讨论】:

  • 那么,jQuery.getJSON 函数加上 "callback=?" 至少可以访问远程内容?
  • @PaperBirdMaster 你在谈论 JSONP,这将允许跨域通信,但前提是服务器遵守。
  • 是的,请阅读我给你的链接下的文件。
  • @RayNicholus 您提供的链接没有问我的一些问题(我在这方面完全是新手),例如:我如何检查远程服务器是否提供/允许 CORS 和/还是 JSONP?
  • 我没有提供任何链接。
猜你喜欢
  • 1970-01-01
  • 2013-04-21
  • 2015-03-05
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多