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选项)。如果我必须改变“内容类型”,我应该在节点服务器上这样做吗?如何?
你必须让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部分
在router.js中,只需在调用get/post方法之前添加代码。它对我来说没有错误。
//Importing modules @Brahmmeswar
const express = require('express');
const router = express.Router();
const Contact = require('../models/contacts');
router.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筛选器文档
谢谢
我遇到了这个问题,我遵循了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++是很好的查看文件编码,并切换到不同的编码:
因为它们运行在不同的端口上,所以它们是不同的JavaScript来源。它们是否在同一台机器/主机名上并不重要。
您需要在服务器(localhost:8080)上启用CORS。看看这个网站:http://enable-cors.org/
你所需要做的就是向服务器添加一个HTTP报头:
Access-Control-Allow-Origin: http://localhost:3000
或者,为了简单起见:
Access-Control-Allow-Origin: *
如果你的服务器试图设置cookie,而你使用withCredentials = true,不要使用“*”
在响应已验证的请求时,服务器必须指定一个域,并且不能使用通配符。
你可以在这里阅读更多关于withCredentials的信息