我有两个域名。我正在尝试通过另一个域中的页面从一个域访问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); }
})
我知道'auth'已正确初始化(记录并检查)。但是,这不起作用。在Firefox的控制台中,我得到了 请求网址:...
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。我不想使用它,主要是因为应用程序将在专用浏览器上不断运行,我担心this issue。更重要的是,我真的想知道我在做什么实际上是错的。我知道出于实际目的,有各种方法可以克服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
在提示我输入用户名和密码的警告框后。
与JSON请求相比,jQuery处理JSONP请求的方式有根本区别吗?如果是这样,我该如何解决这个问题?
感谢。
编辑:这是我找到的。
基本上,因为我需要身份验证,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上的预检请求因此而失败。解 超级用户[.com] / questions / 27268 / how-do-i-disable-the-warning-chrome-give-if-a-security-certificate-is-not-trust(不允许发布更多链接)
答案 0 :(得分:3)
Welp,既然我已经有足够的代表了一段时间,我不妨回答这个问题并接受它。
当您尝试向带有标头的服务器发送GET
json请求时,浏览器会首先发送OPTION
请求以确保您可以访问它。不幸的是,这个OPTION
请求无法随身携带任何身份验证。这意味着如果您要使用auth发送GET
,则服务器必须允许OPTION 而不使用auth 。一旦我这样做,事情就开始起作用了。
答案 1 :(得分:1)
Some examples available here可以进一步说明如何将访问控制与CORS结合起来。特别是有证书的GET示例。访问控制要求请求将withCredentials
标记设置为true
上的XMLHttpRequest
,并且处理OPTIONS
方法的服务器执行以下操作:
Access-Control-Allow-Credentials: true
*
标题中未使用通配符Access-Control-Allow-Origin
。这必须完全根据HTTP访问控制(CORS)上的MDN docs设置为原点。基本上,处理OPTIONS请求的事物需要发送回适当的响应头,以便您可以进行该凭证请求。
在您的问题中,您声明与您交互的服务正在返回Access-Control-Allow-Origin: *
,这与有证书的跨域请求不兼容。这需要具体返回原点。
前面提到的MDN Http访问控制(CORS)文档还链接到服务器端访问控制文档,其中概述了服务器如何可能响应各种跨域请求 - 包括处理需要您发回的跨域凭证POST请求响应OPTIONS方法的正确标头。 You can find that example here。
答案 2 :(得分:0)
为什么不尝试在浏览器中输入要获取JSON的URL,看看会发生什么。听起来你只需要在其他网站上进行身份验证即可访问它。
如果您的网站需要在IE等其他浏览器中运行,那么您将需要JSONP。安全性不允许跨站点请求工作。标题不会改变它。我相信您还需要在标头中添加安全策略。