jQuery.getJSON - 访问控制允许来源问题

发布于 2024-11-15 20:12:04 字数 349 浏览 2 评论 0原文

我正在使用 jQuery 的 $.getJSON() 函数返回一组简短的 JSON 数据。

我的 JSON 数据位于 example.com 等 URL 上。 我没有意识到,但当我访问同一个 url 时,无法加载 JSON 数据。我跟踪控制台,发现由于 Access-Control-Allow-OriginXMLHttpRequest 无法加载。

现在,我已经通读了很多网站,都说使用 $.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

傻比既视感 2024-11-22 20:12:04

很简单,使用 $.getJSON() 函数并在您的 URL 中包含

回调=?

作为参数。这会将调用转换为 JSONP,这是进行跨域调用所必需的。更多信息: http://api.jquery.com/jQuery.getJSON/

It's simple, use $.getJSON() function and in your URL just include

callback=?

as 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/

断念 2024-11-22 20:12:04

您可能很想改用 JSON-P(见下文)。首先快速解释一下。

您提到的标头来自跨源资源共享标准。请注意,人们实际使用的某些浏览器以及其他浏览器(Microsoft 的、叹息)它需要使用特殊的对象(XDomainRequest)而不是 jQuery 使用的标准XMLHttpRequest。它还要求您更改服务器端资源以明确允许其他源 (www.xxxx.com)。

要获取您请求的 JSON 数据,您基本上有三个选择:

  1. 如果可能,您可以通过更正正在加载的文件的位置来最大程度地兼容,以便它们与您的文档具有相同的来源。将它们重新加载到。 (我假设您必须通过 Ajax 加载它们,因此会出现同源策略问题。)

  2. 使用JSON-P,不受SOP约束。 jQuery 在其 ajax 调用中内置了对它的支持(只需将 dataType 设置为“jsonp”,jQuery 将完成所有客户端工作)。这需要服务器端进行更改,但不是很大;基本上,生成 JSON 响应的任何内容都只是查找名为“callback”的查询字符串参数,并将 JSON 包装在调用该函数的 JavaScript 代码中。例如,如果您当前的 JSON 响应是:

    {"weather": "沉闷的开始,但很快就会变成晴朗的夏日。"}
    

    您的脚本将查找“callback”查询字符串参数(假设该参数的值为“jsop123”)并将该 JSON 包装在 JavaScript 函数调用的语法中:

    jsonp123({"weather": "沉闷的开始,但很快就会变成晴朗的夏日。"});
    

    就是这样。 JSON-P 非常广泛兼容(因为它通过 JavaScript script 标签工作)。不过,JSON-P 仅适用于 GET,不适用于 POST(同样是因为它通过 script 标签工作)。

  3. 使用 CORS(与您引用的标头相关的机制)。详细信息请参阅上面链接的规范,但基本上是:

    A.浏览器将使用 OPTIONS HTTP 动词(方法)向您的服务器发送一条“预检”消息。它将包含使用 GETPOST 发送的各种标头以及标头“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.浏览器将查看您的响应,并查看是否允许向您发送实际的 GETPOST。如果是这样,它将再次发送该请求,并带有“Origin”和各种“Access-Control-Request-xyz”标头。

    D.您的 PHP 再次检查这些标头,以确保它们仍然正常,如果正常,则响应请求。

    代码中(我没有做过太多 PHP,所以我不尝试在这里做 PHP 语法):

    // 找出请求所要求的内容
    corsOrigin = get_request_header("来源")
    corsMethod = get_request_header("访问控制请求方法")
    corsHeaders = get_request_header("访问控制请求标头")
    如果 corsOrigin 为 null 或“null”{
        // 来自 `file://` 路径的请求似乎没有经过
        // 原点或以“null”(字面意思)作为原点。
        // 就我而言,为了测试,我想允许这些,所以我输出
        //“*”,但您可能想采用另一种方式。
        坐标原点=“*”
    }
    
    // 决定是否接受带有这些标头的请求
    // 如果是这样:
    
    // 响应标头说明允许的内容(这里我们只是回显它们的内容)
    // 要求,但我们可能使用“*”[all]而不是实际的来源
    //“访问控制允许来源”之一)
    set_response_header("访问控制允许来源", corsOrigin)
    set_response_header("访问控制允许方法", corsMethod)
    set_response_header("访问控制允许标头", corsHeaders)
    如果 HTTP 请求方法是“OPTIONS”{
        // 完成,没有正文响应 OPTIONS
        停止
    }
    // 在这里处理 GET 或 POST;输出响应的正文
    

    再次强调这是伪代码。

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 standard XMLHttpRequest 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:

  1. 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.)

  2. Use JSON-P, which isn't subject to the SOP. jQuery has built-in support for it in its ajax call (just set dataType 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:

    {"weather": "Dreary start but soon brightening into a fine summer day."}
    

    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:

    jsonp123({"weather": "Dreary start but soon brightening into a fine summer day."});
    

    That's it. JSON-P is very broadly compatible (because it works via JavaScript script tags). JSON-P is only for GET, though, not POST (again because it works via script tags).

  3. 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 the GET or POST as well as the headers "Origin", "Access-Control-Request-Method" (e.g., GET or POST), 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 or POST. 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):

    // Find out what the request is asking for
    corsOrigin = get_request_header("Origin")
    corsMethod = get_request_header("Access-Control-Request-Method")
    corsHeaders = get_request_header("Access-Control-Request-Headers")
    if corsOrigin is null or "null" {
        // Requests from a `file://` path seem to come through without an
        // origin or with "null" (literally) as the origin.
        // In my case, for testing, I wanted to allow those and so I output
        // "*", but you may want to go another way.
        corsOrigin = "*"
    }
    
    // Decide whether to accept that request with those headers
    // If so:
    
    // Respond with headers saying what's allowed (here we're just echoing what they
    // asked for, except we may be using "*" [all] instead of the actual origin for
    // the "Access-Control-Allow-Origin" one)
    set_response_header("Access-Control-Allow-Origin", corsOrigin)
    set_response_header("Access-Control-Allow-Methods", corsMethod)
    set_response_header("Access-Control-Allow-Headers", corsHeaders)
    if the HTTP request method is "OPTIONS" {
        // Done, no body in response to OPTIONS
        stop
    }
    // Process the GET or POST here; output the body of the response
    

    Again stressing that this is pseudo-code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文