3

我有两个域。我正在尝试通过另一个域上的页面从一个域访问 JSON 对象。我已经阅读了有关此问题的所有内容,但仍然无法弄清楚。

提供 JSON 的域具有以下设置:

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
Header set Access-Control-Allow-Headers "origin, authorization, accept"

在我的另一个域中,我正在调用以下内容:

$.ajax({
         type:'get',
         beforeSend: function(xhr) {
             var auth = // authentication; 
             xhr.setRequestHeader("Authorization", "Basic " + auth);
         }
         url:myUrl,
         dataType:'json',
         error: function(xhr, textStatus, errorThrown) { console.log(textStatus, errorThrown); }
      })

我知道“身份验证”已正确初始化(记录并检查)。但是,这不起作用。在 Firefox 的控制台中,我得到 Request URL: ...

Request Method:
OPTIONS

Status Code:
HTTP/1.1 401 Authorization Required

如果我摆脱这beforeSend:...部分,我会看到以下内容

Request Method:
GET

Status Code:
HTTP/1.1 401 Authorization Required

但是,提供 JSON 的域也可以提供 JSONP。我不想用这个,主要是因为应用程序会在专用浏览器上不断运行,我很担心这个问题。更重要的是,我真的很想知道我所做的事情到底出了什么问题。我知道出于实际目的,有多种方法可以克服 JSONP 内存泄漏(例如不使用 jQuery)。

无论如何,当我使用 JSONP 时,我的代码如下所示:

$.ajax({
    url:newUrl,
    dataType:'jsonp',
    jsonp:'jsonp'
}).done(function(d){console.log(d)})

这得到以下

Request Method:
GET

Status Code:
HTTP/1.1 200 OK

在它提示我输入用户名和密码的警报框之后。

jQuery 处理 JSONP 请求的方式与 JSON 请求的方式有根本的区别吗?如果是这样,我该如何解决这个问题?

谢谢。

编辑:这是我找到的。

基本上,因为我需要身份验证,所以 GET 请求正在发送一个 Authorization 标头。但是,这不是一个“简单”的标头,因此浏览器正在发送一个飞行前请求(OPTIONS)。但是,此预检请求没有任何身份验证,因此服务器拒绝了它。“解决方案”是将服务器设置为让 OPTIONS 请求不需要身份验证,并向其报告 HTTP 状态 200。

参考:http ://www.kinvey.com/blog/item/61-kinvey-adds-cross-origin-resource-sharing-cors

mail-archive[.com]/c-user@axis.apache.org/msg00790.html(不允许发布更多链接)

不幸的是,“解决方案”仅适用于 Firefox 而不是 Chrome。Chrome 只是将请求显示为红色,但没有向我提供有关失败原因的更多信息。

编辑 2:在 Chrome 上修复:我试图从中获取数据的服务器具有不受信任的安全证书。因此,Chrome 上的预检请求失败。解决方案 superuser[.com]/questions/27268/how-do-i-disable-the-warning-chrome-gives-if-a-security-certificate-is-not-trust(不允许发布更多链接)

4

3 回答 3

3

Welp,现在我已经有足够的代表了,我不妨回答这个问题并接受它。

当您尝试向GET带有标头的服务器发送 json 请求时,浏览器首先会发送一个OPTION请求以确保您可以访问它。不幸的是,这个OPTION请求不能携带任何身份验证。这意味着如果你想发送一个GET带有 auth 的,服务​​器必须允许一个没有 auth的 OPTION 。一旦我这样做了,事情就开始起作用了。

于 2013-05-18T07:54:16.813 回答
1

此处提供的一些示例可以进一步说明访问控制如何与 CORS 结合使用。特别是经过认证的 GET 示例。访问控制要求请求将withCredentials标志设置为trueon XMLHttpRequest,并且为处理该OPTIONS方法的服务器做两件事:

  1. Access-Control-Allow-Credentials: true
  2. *不要在Access-Control-Allow-Origin标题中使用通配符。这必须完全根据MDN 文档关于 HTTP 访问控制 (CORS) 设置为原点。

本质上,处理 OPTIONS 请求的事物需要发回适当的响应标头,以便您可以发出该凭证请求。

在您的问题中,您说您正在与之交互的服务正在返回Access-Control-Allow-Origin: *,这与凭证的跨域请求不兼容。这需要专门返回原点。

前面提到的 MDN Http 访问控制 (CORS) 文档还链接到服务器端访问控制文档,该文档概述了服务器可能如何响应各种跨域请求 - 包括处理要求您发回正确标头的跨域凭据 POST 请求响应 OPTIONS 方法。您可以在此处找到该示例

于 2015-06-30T14:54:52.293 回答
0

为什么不尝试在浏览器中输入要从中获取 JSON 的 URL 并查看会发生什么。听起来您实际上只需要在其他网站上进行身份验证即可访问它。

如果您的网站需要在 IE 等其他浏览器中运行,顺便说一下,您将需要 JSONP。安全性不允许跨站点请求工作。标题不会改变这一点。我相信您还需要在标题中添加安全策略。

于 2012-06-26T00:59:13.653 回答