向localhost上的不同端口发出请求时,缺少CORS头“Access-Control-Allow-Origin”

时间:2017-02-16 10:15:20

标签: javascript cors

我在端口6000上运行了一个节点Web服务器(express)。

调用http://localhost:6000/时,index.html将提供给客户端,该客户端有一个运行的脚本logic.js

var xhr = new XMLHttpRequest();
var url = 'http://localhost:4000/endpoint';
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-type', 'application/json');
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log('endpoint');
    callback(xhr.responseText);
  }
};
xhr.send(JSON.stringify({'key': 'value'}));

在端口4000上运行另一个快速服务器。

服务器设置一个端点,它只返回请求主体提交的内容:

app.route('/segment')
  .post(bodyParser.json(), function(req, res) {
  res.set('Access-Control-Allow-Origin', '*');
  res.send(req.body);
});

当我访问http://localhost:6000/时,我在浏览器控制台中看到了这一点:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:4100/segment. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)

在原型设计过程中有没有办法绕过这个?

3 个答案:

答案 0 :(得分:4)

您的端点可能不提供OPTIONS HTTP方法,浏览器用它来检查CORS标头(在它们发出真实请求之前)。

如果您在开发和生产中需要不同的CORS标头,我认为最好的方法是添加一个新的后端配置选项,其中包含允许来源的值,并从一些全局响应过滤器中提供它们。

答案 1 :(得分:1)

您已设置xhr.setRequestHeader('Content-type', 'application/json');,因此这是preflighted request(经验法则:对于HTML表单的enctype属性而言不是有效值的Content-Type将触发预先要求)。

您的服务器端代码仅设置Access-Control-Allow-Origin标头以响应POST请求。您需要编写服务器端代码以响应预检OPTIONS请求。

答案 2 :(得分:1)

以下是解决此问题的几种方法:

最佳:CORS标头(需要更改服务器)

CORS(跨域资源共享)是一种服务器说“我会接受您的请求,即使您来自不同的来源。”这需要服务器的合作 - 所以如果您不能修改服务器(例如,如果您使用的是外部API),这种方法将无效。

修改服务器以添加标头Access-Control-Allow-Origin:*以从任何地方启用跨源请求(或指定域而不是*)。这应该可以解决你的问题。

第二选择:代理服务器

如果无法修改服务器,则可以运行自己的代理。如果该代理与您的页面不在同源,则此代理可以返回Access-Control-Allow-Origin标头。

您不会向某个远程服务器发送API请求,而是向您的代理发出请求,代理会将它们转发到远程服务器。以下是一些代理选项。

第三选择:JSONP(需要服务器支持)

如果CORS和代理服务器不适合您,JSONP可能会有所帮助。您基本上使用回调参数发出GET请求:

(get)http://api.example.com/endpoint?callback=foo 服务器将JSON回复包含在对回调的函数调用中,您可以在其中处理它:

foo({“你的”:“json”,这里:true}) 存在一些缺点,特别是JSONP仅支持GET请求,并且您仍然需要协作服务器。