【问题标题】:jQuery.getJSON - Access-Control-Allow-Origin IssuejQuery.getJSON - 访问控制允许来源问题
【发布时间】:2023-04-01 23:10:02
【问题描述】:

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

我将 JSON 数据放在诸如 example.com 之类的 URL 上。 我没有意识到,但是当我访问同一个 url 时,无法加载 JSON 数据。我通过控制台发现XMLHttpRequest由于Access-Control-Allow-Origin而无法加载。

现在,我已经阅读了很多刚刚说要使用 $.getJSON() 的网站,这可以解决,但显然它没有用。我应该在标题或函数中更改一些内容吗?

非常感谢您的帮助。

【问题讨论】:

  • 也许你可能想看看 JSONP:en.wikipedia.org/wiki/JSONP.
  • 另一种方法是使用代理(例如 PHP curl)转发您的请求和响应(如果您可以使用)。

标签: javascript jquery json xmlhttprequest access-control


【解决方案1】:

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

回调=?

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

【讨论】:

  • 这完全取决于服务器接受额外的回调参数,它可能不会在所有情况下都这样做。
  • 这在 100% 的情况下都不起作用,就好像服务器没有设置为服务器 jsonp 一样,它仍然返回 json,您会在其中收到错误。
  • 在我的情况下,有时我会遇到 CORS 问题,而不是每次打开网站时。所以现在我已经应用了这个解决方法,但我看不到我是否已经解决了。
【解决方案2】:

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

您提到的标头来自Cross Origin Resource Sharing 标准。请注意,人们实际使用的某些浏览器是not supported,而在其他浏览器(微软的,sigh)上,它需要使用一个特殊的对象(XDomainRequest)而不是标准的XMLHttpRequest jQuery用途。它还要求您更改服务器端资源以明确允许其他来源 (www.xxxx.com)。

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

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

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

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

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

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

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

  3. 使用 CORS(与您引用的标头相关的机制)。详情见the specification linked above,但基本上:

    A.浏览器将使用OPTIONS HTTP 动词(方法)向您的服务器发送“预检”消息。它将包含它将与GETPOST 一起发送的各种标头以及标头“Origin”、“Access-Control-Request-Method”(例如,GETPOST)和“ 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 再次检查这些标头以确保它们仍然正常,如果正常则响应请求。

    pseudo-code中(我没做过多少PHP,所以这里不尝试做PHP语法):

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

    再次强调这是伪代码。

【讨论】:

  • 有没有办法利用 jQuery 做到这一点?或者,我可以设置一个标题(通过 PHP)来让它工作吗?
  • @Mike:哪个“这个”?如果您的意思是 JSON-P,是的,jQuery 在其 ajax 调用中支持它;我在上面添加了一些细节。如果您的意思是 CORS,那么是的,这是您通过 PHP 设置的标头以响应 OPTIONS HTTP 请求,并再次响应 GETPOST;我也为此添加了一些细节。但是,如果您有任何机会可以移动文件以使它们位于同一来源,那就太矫枉过正了。
  • @T.J.Crowder 所以 $.getJSON 不起作用?我们是否需要使用 ajax 之类的其他方法并设置标题?
  • @Dinesh: $.getJSON 工作正常provided 1)这是一个同源请求,或者 2)浏览器和服务器都支持 CORS 并且服务器允许源, 或 3) 服务器提供 JSON-P 接口,你告诉 jQuery 你正在使用 JSON-P,方法是在你给 $.getJSON 的 URL 中使用 ?callback=
  • @T.J.Crowder 好的.. 你能回答这个问题吗 - stackoverflow.com/questions/22795561/…
猜你喜欢
  • 2013-12-17
  • 2020-10-16
  • 2013-11-15
  • 2015-12-26
  • 2016-05-07
  • 1970-01-01
  • 2021-09-07
相关资源
最近更新 更多