2

AngularJS 使用 REST 对服务器端进行身份验证,并获取 JSESSIONID cookie。在下一步中,我将尝试使用 REST 从服务器端获取一些 JSON 数据以及在上一步中获得的会话 cookie。这是客户端代码:

getSomeJSONDataFromServer:function() {
var deferred = $q.defer();
$http({
    method: 'POST',
    withCredentials: true,
    url: "http://domain.name/app/someURL",
    headers:{
        'Accept':'application/json',
        'Content-Type':'application/json; charset=utf-8',
        'Access-Control-Request-Headers': 'X-Requested-With, content-type, accept, origin, withcredentials'
    }
})
.success(function(data, status, headers, config) {
    // handle data
})
.error(function(data, status, headers, config) {
    // handle error
});
return deferred.promise;
}

上面的代码工作正常:

没有正文的 CORS $http 请求

当我在上面的 POST 请求正文中发送一些数据时,问题就开始了。

...
$http({
    method: 'POST',
    withCredentials: true,
    url: "http://domain.name/app/someURL",
    headers:{
        'Accept':'application/json',
        'Content-Type':'application/json; charset=utf-8',
        'Access-Control-Request-Headers': 'X-Requested-With, content-type, accept, origin, withcredentials'
    },
    data: '{}'
})
.success(...

上面的代码在 prelight 请求中失败:

带有正文的 CORS $http 请求失败!

看起来服务器启动了一个新会话,因为会话 cookie 由于某种原因没有发送。无论如何,我觉得我错过了一些非常简单的东西,一些标题或类似的东西......任何想法都值得赞赏。提前致谢。

4

3 回答 3

7

阿米尔,

请允许我帮助您和其他人清楚地了解处理 CORS 时的预期内容,例如:

指数:

  • 简单 CORS 版本
  • 预检 CORS 版本
  • 带有凭据的请求

简单 CORS 版本

  1. 您可以使用 GET、HEAD 或 POST:
    • 在任何方法情况下,您都不能设置自定义标头
    • 您始终可以让服务器端通过 Access-Control-Allow-Origin 标头限制域访问。
  2. 如果 POST 有请求数据:
    • Content-Type必须是以下之一:
      • 应用程序/x-www-form-urlencoded
      • 多部分/表单数据
      • 文本/html

这个简单的版本显然不是你的情况......

预检 CORS 版本

  1. 您可以使用 GET、HEAD 或 POST:
    • 在任何方法情况下,您都可以设置定义标头
    • 您始终可以让服务器端通过 Access-Control-Allow-Origin 标头限制域访问。
  2. 如果 POST 有请求数据:
    • Content-Type可以是以下各项:
      • 应用程序/x-www-form-urlencoded
      • 多部分/表单数据
      • 文本/html
    • Content-Type也可以其他类型:
      • 应用程序/json
      • 应用程序/xml
      • 文本/xml
      • 等等

这个 PREFLIGHTED 版本显然是你的情况......

带有凭据的请求

  1. 如果您使用cookie调用调用,则需要设置请求的以下参数部分:
    • withCredentials = true

带有凭证的请求显然也是您的情况......

于 2014-08-11T20:19:09.387 回答
3

根据带有预检规范凭据的跨域请求,即会话 cookie,不会在预检请求中发送,因此解决方案是在您的 REST 服务器端禁用 OPTIONS 请求的安全性,并仅允许 OPTIONS 请求没有会话 cookie 的请求。

当然要小心不要禁用 POST 和 GET 请求的安全性。

于 2014-03-14T14:09:10.350 回答
0

根据https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

为了在 POST 中允许 cookie,需要使用 Access-Control-Allow-Credentials 配置远程:true。

如果您使用的是码头,则需要配置

    <init-param>
        <param-name>allowCredentials</param-name>
        <param-value>true</param-value>
    </init-param>

并引用 MDN 文章,

重要提示:在响应凭据请求时,服务器必须指定域,并且不能使用通配符。如果标头通配符为:Access-Control-Allow-Origin: *,上述示例将失败。由于 Access-Control-Allow-Origin 明确提及http://foo.example,因此将凭据识别内容返回给调用 Web 内容。

于 2014-04-19T13:48:24.877 回答