XMLHttpRequest cannot load http://localhost:8080/api/test. Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. 

我读过跨域ajax请求,了解底层的安全问题。在我的例子中,两台服务器在本地运行,并且喜欢在测试期间启用跨域请求。

localhost:8080 - Google Appengine dev server
localhost:3000 - Node.js server

当我的页面从节点服务器加载时,我发出ajax请求到localhost:8080 - GAE服务器。什么是最简单,最安全的(不想启动chrome禁用web-security选项)。如果我必须改变“内容类型”,我应该在节点服务器上这样做吗?如何?


当前回答

我遇到了这个问题,我遵循了php方面(设置头部)和react (axios withcredential =true)的所有推荐代码片段,但我无法摆脱这个错误。

在php中我有:

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT, GET, POST");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");

最后,我注意到这些头文件没有出现在响应中。

响应应该是这样的:

显然,出于某种原因,我的vscode开始将文件保存为UTF8-BOM。结果,报头立即被发送,所有后续的header(..)语句都被忽略,因为报头已经被发送。

有两个有用的php命令可以检查这个问题:headers_list()和headers_sent()

notepad++是很好的查看文件编码,并切换到不同的编码:

其他回答

如果你是谷歌Chrome浏览器,试着安装这个插件:

https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi/related

将此添加到您的NodeJS服务器,如下所示:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

如果你得到了403,请减少WEB.XML tomcat配置中的过滤器如下:

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
</filter>

如果你正在使用express,你可以使用cors中间件如下所示:

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

如果你需要一个快速的工作围绕在Chrome ajax请求,这个Chrome插件自动允许你访问任何来源的任何网站通过添加适当的响应头

Chrome扩展Allow-Control-Allow-Origin: *