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选项)。如果我必须改变“内容类型”,我应该在节点服务器上这样做吗?如何?


当前回答

将此添加到您的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();
});

其他回答

我终于得到了apache Tomcat8的答案

您必须编辑tomcat web.xml文件。

可能会在webapps文件夹里,

sudo gedit /opt/tomcat/webapps/your_directory/WEB-INF/web.xml

找到它并编辑它

<web-app>


<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>
  <init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
  </init-param>
</filter>


<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>



</web-app>

这将允许所有主机访问控制允许起源。 如果需要将其从所有主机更改为仅您的主机,则可以编辑

<param-name>cors.allowed.origins</param-name>
<param-value>http://localhost:3000</param-value>

以上代码从*到您的http://your_public_IP或http://www.example.com

您可以参考Tomcat筛选器文档

谢谢

我接受@火箭危险品的答案,因为它让我找到了解决方案。我需要在GAE服务器上设置标头。我必须设置这些

"Access-Control-Allow-Origin" -> "*"
"Access-Control-Allow-Headers" -> "Origin, X-Requested-With, Content-Type, Accept"

仅设置“Access-Control-Allow-Origin”出错

Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers.

同样,如果需要发送认证令牌,也要添加这个

"Access-Control-Allow-Credentials" -> "true"

同样,在客户端,设置withCredentials

这将导致2个请求发送到服务器,其中一个带有OPTIONS。认证cookie没有随它一起发送,因此需要在外部认证处理。

如果您的服务器是server=express(),只需在下一行添加server.use(cors())。例如:

server.js

const express = require('express')
const cors = require('cors')
server=express()
server.use(cors())

server.get('/',(req,res)=>{
    res.send({"name":"aakash","name2":"aakash4dev"})
})
server.listen(3000)

index . html

<script>
    fetch('http://localhost:3000/')
  .then(res=> res.json())
  .then(data => console.log(data))
</script>

你必须让CORS来解决这个问题

如果你的应用是用简单的node.js创建的

在你的响应头中设置它

var http = require('http');

http.createServer(function (request, response) {
response.writeHead(200, {
    'Content-Type': 'text/plain',
    'Access-Control-Allow-Origin' : '*',
    'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE'
});
response.end('Hello World\n');
}).listen(3000);

如果你的应用是用express framework创建的

使用CORS中间件

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', "*");
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
}

并通过

app.configure(function() {
    app.use(allowCrossDomain);
    //some other code
});    

这里有两个参考链接

how-to-allow-cors-in-express-nodejs dive -into-node-js-very-first-app #参见Ajax部分

如果有人正在寻找解决方案,如果您正在使用express,这里是快速解决方案。

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

1)使用NPM install cors—save

2) import it [require] const cors = require('cors')

3)使用它作为中间件app.use(cors())

详细的安装和使用cors。 就是这样,希望它能起作用。