jQuery,CORS,JSON(没有填充)和身份验证问题

时间:2012-06-26 00:49:58

标签: javascript jquery ajax jsonp cors

我有两个域名。我正在尝试通过另一个域中的页面从一个域访问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(不允许发布更多链接)

3 个答案:

答案 0 :(得分:3)

Welp,既然我已经有足够的代表了一段时间,我不妨回答这个问题并接受它。

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

答案 1 :(得分:1)

Some examples available here可以进一步说明如何将访问控制与CORS结合起来。特别是有证书的GET示例。访问控制要求请求将withCredentials标记设置为true上的XMLHttpRequest,并且处理OPTIONS方法的服务器执行以下操作:

  1. 设置Access-Control-Allow-Credentials: true
  2. *标题中未使用通配符Access-Control-Allow-Origin。这必须完全根据HTTP访问控制(CORS)上的MDN docs设置为原点。
  3. 基本上,处理OPTIONS请求的事物需要发送回适当的响应头,以便您可以进行该凭证请求。

    在您的问题中,您声明与您交互的服务正在返回Access-Control-Allow-Origin: *,这与有证书的跨域请求不兼容。这需要具体返回原点。

    前面提到的MDN Http访问控制(CORS)文档还链接到服务器端访问控制文档,其中概述了服务器如何可能响应各种跨域请求 - 包括处理需要您发回的跨域凭证POST请求响应OPTIONS方法的正确标头。 You can find that example here

答案 2 :(得分:0)

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

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