【发布时间】: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