【问题标题】:Access-Control-Allow-Origin in preflight response doesn't enable cross-domain access预检响应中的 Access-Control-Allow-Origin 不启用跨域访问
【发布时间】:2014-10-27 03:26:31
【问题描述】:

我正在尝试使用 AJAX 向 nodeJS 服务器发送 CORS 请求。我想返回一些 JSON 数据。我在网上找到了许多教程,它们都说同样的话,我试过了,但我无法让它工作。这是 AJAX 请求:

$.ajax({
        url: "http://some.other.url.com:8880",
        type: "GET",
        crossDomain: true,
        contentType: 'application/json'
    }).then(function(response) {
        $scope.allData = jQuery.parseJSON( response );
        console.log($scope.allData);
    }).fail(function(response) {
});

这是服务器上的代码:

var path = url.parse(req.url).pathname,
    match = router.match(path),
    rescode;

    console.log("---: " + req.method);

if (req.method === 'OPTIONS') {
    var headers = {};
    headers["Access-Control-Allow-Origin"] = "*";
    headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
    headers["Access-Control-Allow-Credentials"] = false;
    headers["Access-Control-Max-Age"] = '86400'; // 24 hours
    headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
    res.writeHead(200, headers);
    return res.end();
}

我也试过不返回 res.end(),即不返回 OPTIONS 预检请求,这也不起作用。

--编辑-- 这是控制台中的实际错误消息:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://other.domain.com:8880/. This can be fixed by moving the resource to the same domain or enabling CORS.

服务器正在接收请求。 OPTIONS 和 GET 请求都在访问服务器并得到响应。实际上,在发出 AJAX 请求的页面的控制台日志中,我可以单击 CORS 错误并查看响应,这是正确的数据。但我似乎无法让 javascript 继续。

关于.done 与.then,它们似乎可以互换。或者至少,在这个例子中,.then 和 .fail 工作得很好。

【问题讨论】:

  • 那么当你查看它的错误控制台时浏览器会说什么?不同端口上的跨域请求通常是被禁止的,所以我很确定它会告诉你端口不匹配。
  • 所以您正在为 OPTIONS 预检发送 CORS 标头。您是否为实际的 GET 请求发送 CORS 标头?
  • 我很确定 $.ajax 会返回“完成”承诺而不是“那么”?你得到回应了吗?请提供有关您看到的错误的更多信息。
  • 请准确指出失败的原因。服务器是否曾经看到过 GET 请求(即,console.log("---: " + req.method) 是否曾经输出过 ---: GET)?你在客户端看到了什么错误信息?
  • 查看我的编辑以获取对这些问题的回复

标签: ajax node.js cors


【解决方案1】:

您在 OPTIONS 预检响应中正确设置了 CORS 标头,但您还需要在实际 GET 响应中设置 Access-Control-Allow-Origin(您的来源或 *)。无论是否有预检响应,GET 响应都应使用相同的 CORS 标头进行响应。这意味着它必须发送适当的 CORS 标头,但它不需要发送除 Access-Control-Allow-Origin 之外的任何内容。 (如果涉及到其他非简单组件如非简单动词或标题,它们将在预检中被允许或拒绝;实际的 GET 响应不需要担心它们。)

Enable CORS 站点有一个CORS testing tool,可帮助您查看您指定的请求中涉及的标头。我已经使用该工具设置了test similar to your case(带有非简单Content-Type 标头的GET)。如果我们检查该测试的结果(小心 - 步骤有点乱,但它们都在那里),我们会看到一个预检响应:

Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
...
Access-Control-Allow-Origin: http://client.cors-api.appspot.com
Access-Control-Allow-Headers: X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept

以及最终的 CORS 响应:

Content-Length: 0
Content-Type: application/json
Access-Control-Allow-Origin: http://client.cors-api.appspot.com
Cache-Control: no-cache

如您所见,GET 响应还有一个 Access-Control-Allow-Origin 标头,没有其他 CORS 标头。如果您还有任何不确定性,请随时调整该工具的设置以运行各种其他测试用例。

【讨论】:

  • 终于!我在网上阅读的教程或信息都没有提到包括 GET 请求和 OPTIONS 请求的标头。
猜你喜欢
  • 2017-05-17
  • 2013-11-23
  • 2019-09-09
  • 1970-01-01
  • 2016-04-24
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多