jQuery.getJSON - 访问控制允许来源问题
我正在使用 jQuery 的 $.getJSON()
函数返回一组简短的 JSON 数据。
我的 JSON 数据位于 example.com
等 URL 上。 我没有意识到,但当我访问同一个 url 时,无法加载 JSON 数据。我跟踪控制台,发现由于 Access-Control-Allow-Origin
,XMLHttpRequest
无法加载。
现在,我已经通读了很多网站,都说使用 $.getJSON()
这就是解决方法,但显然它不起作用。我应该在标题或函数中更改某些内容吗?
非常感谢您的帮助。
I'm jusing jQuery's $.getJSON()
function to return a short set of JSON data.
I've got the JSON data sitting on a url such as example.com
.
I didn't realize it, but as I was accessing that same url, the JSON data couldn't be loaded. I followed through the console and found that XMLHttpRequest
couldn't load due to Access-Control-Allow-Origin
.
Now, I've read through, a lot of sites that just said to use $.getJSON()
and that would be the work around, but obviously it didn't work. Is there something I should change in the headers or in the function?
Help is greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
很简单,使用
$.getJSON()
函数并在您的 URL 中包含作为参数。这会将调用转换为 JSONP,这是进行跨域调用所必需的。更多信息: http://api.jquery.com/jQuery.getJSON/
It's simple, use
$.getJSON()
function and in your URL just includeas a parameter. That will convert the call to JSONP which is necessary to make cross-domain calls. More info: http://api.jquery.com/jQuery.getJSON/
您可能很想改用 JSON-P(见下文)。首先快速解释一下。
您提到的标头来自跨源资源共享标准。请注意,人们实际使用的某些浏览器以及其他浏览器(Microsoft 的、叹息)它需要使用特殊的对象(
XDomainRequest
)而不是 jQuery 使用的标准XMLHttpRequest
。它还要求您更改服务器端资源以明确允许其他源 (www.xxxx.com
)。要获取您请求的 JSON 数据,您基本上有三个选择:
如果可能,您可以通过更正正在加载的文件的位置来最大程度地兼容,以便它们与您的文档具有相同的来源。将它们重新加载到。 (我假设您必须通过 Ajax 加载它们,因此会出现同源策略问题。)
使用JSON-P,不受SOP约束。 jQuery 在其
ajax
调用中内置了对它的支持(只需将dataType
设置为“jsonp”,jQuery 将完成所有客户端工作)。这需要服务器端进行更改,但不是很大;基本上,生成 JSON 响应的任何内容都只是查找名为“callback”的查询字符串参数,并将 JSON 包装在调用该函数的 JavaScript 代码中。例如,如果您当前的 JSON 响应是:您的脚本将查找“callback”查询字符串参数(假设该参数的值为“jsop123”)并将该 JSON 包装在 JavaScript 函数调用的语法中:
就是这样。 JSON-P 非常广泛兼容(因为它通过 JavaScript
script
标签工作)。不过,JSON-P 仅适用于GET
,不适用于POST
(同样是因为它通过script
标签工作)。使用 CORS(与您引用的标头相关的机制)。详细信息请参阅上面链接的规范,但基本上是:
A.浏览器将使用
OPTIONS
HTTP 动词(方法)向您的服务器发送一条“预检”消息。它将包含使用GET
或POST
发送的各种标头以及标头“Origin”、“Access-Control-Request-Method”(例如,< code>GET 或POST
)和“Access-Control-Request-Headers”(要发送的标头)。B.您的 PHP 根据该信息决定请求是否正常,如果可以,则使用“Access-Control-Allow-Origin”、“Access-Control-Allow-Methods”和“Access-Control-Allow-Headers”进行响应标头及其允许的值。您不会随该响应一起发送任何正文(页面)。
C.浏览器将查看您的响应,并查看是否允许向您发送实际的
GET
或POST
。如果是这样,它将再次发送该请求,并带有“Origin”和各种“Access-Control-Request-xyz”标头。D.您的 PHP 再次检查这些标头,以确保它们仍然正常,如果正常,则响应请求。
在伪代码中(我没有做过太多 PHP,所以我不尝试在这里做 PHP 语法):
再次强调这是伪代码。
You may well want to use JSON-P instead (see below). First a quick explanation.
The header you've mentioned is from the Cross Origin Resource Sharing standard. Beware that it is not supported by some browsers people actually use, and on other browsers (Microsoft's, sigh) it requires using a special object (
XDomainRequest
) rather than the standardXMLHttpRequest
that jQuery uses. It also requires that you change server-side resources to explicitly allow the other origin (www.xxxx.com
).To get the JSON data you're requesting, you basically have three options:
If possible, you can be maximally-compatible by correcting the location of the files you're loading so they have the same origin as the document you're loading them into. (I assume you must be loading them via Ajax, hence the Same Origin Policy issue showing up.)
Use JSON-P, which isn't subject to the SOP. jQuery has built-in support for it in its
ajax
call (just setdataType
to "jsonp" and jQuery will do all the client-side work). This requires server side changes, but not very big ones; basically whatever you have that's generating the JSON response just looks for a query string parameter called "callback" and wraps the JSON in JavaScript code that would call that function. E.g., if your current JSON response is:Your script would look for the "callback" query string parameter (let's say that the parameter's value is "jsop123") and wraps that JSON in the syntax for a JavaScript function call:
That's it. JSON-P is very broadly compatible (because it works via JavaScript
script
tags). JSON-P is only forGET
, though, notPOST
(again because it works viascript
tags).Use CORS (the mechanism related to the header you quoted). Details in the specification linked above, but basically:
A. The browser will send your server a "preflight" message using the
OPTIONS
HTTP verb (method). It will contain the various headers it would send with theGET
orPOST
as well as the headers "Origin", "Access-Control-Request-Method" (e.g.,GET
orPOST
), and "Access-Control-Request-Headers" (the headers it wants to send).B. Your PHP decides, based on that information, whether the request is okay and if so responds with the "Access-Control-Allow-Origin", "Access-Control-Allow-Methods", and "Access-Control-Allow-Headers" headers with the values it will allow. You don't send any body (page) with that response.
C. The browser will look at your response and see whether it's allowed to send you the actual
GET
orPOST
. If so, it will send that request, again with the "Origin" and various "Access-Control-Request-xyz" headers.D. Your PHP examines those headers again to make sure they're still okay, and if so responds to the request.
In pseudo-code (I haven't done much PHP, so I'm not trying to do PHP syntax here):
Again stressing that this is pseudo-code.