node.js 为什么将 CORS 标头添加到 OPTIONS 路由不允许浏览器访问我的 API?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7067966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
提问by mikong
I am trying to support CORS in my Node.js application that uses the Express.js web framework. I have read a Google group discussionabout how to handle this, and read a few articles about how CORS works. First, I did this (code is written in CoffeeScript syntax):
我正在尝试在使用 Express.js Web 框架的 Node.js 应用程序中支持 CORS。我已阅读有关如何处理此问题的 Google 小组讨论,并阅读了几篇有关 CORS 工作原理的文章。首先,我这样做了(代码是用 CoffeeScript 语法编写的):
app.options "*", (req, res) ->
res.header 'Access-Control-Allow-Origin', '*'
res.header 'Access-Control-Allow-Credentials', true
# try: 'POST, GET, PUT, DELETE, OPTIONS'
res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS'
# try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
res.header 'Access-Control-Allow-Headers', 'Content-Type'
# ...
It doesn't seem to work. It seems like my browser (Chrome) is not sending the initial OPTIONS request. When I just updated the block for the resource I need to submit a cross-origin GET request to:
它似乎不起作用。我的浏览器(Chrome)似乎没有发送初始 OPTIONS 请求。当我刚刚更新资源块时,我需要提交一个跨域 GET 请求到:
app.get "/somethingelse", (req, res) ->
# ...
res.header 'Access-Control-Allow-Origin', '*'
res.header 'Access-Control-Allow-Credentials', true
res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'
res.header 'Access-Control-Allow-Headers', 'Content-Type'
# ...
It works (in Chrome). This also works in Safari.
它有效(在 Chrome 中)。这也适用于 Safari。
I have read that...
我读过那...
In a browser implementing CORS, each cross-origin GET or POST request is preceded by an OPTIONS request that checks whether the GET or POST is OK.
在实现 CORS 的浏览器中,每个跨域 GET 或 POST 请求前面都有一个检查 GET 或 POST 是否正常的 OPTIONS 请求。
So my main question is, how come this doesn't seem to happen in my case? Why isn't my app.options block called? Why do I need to set the headers in my main app.get block?
所以我的主要问题是,为什么在我的情况下似乎没有发生这种情况?为什么我的 app.options 块没有被调用?为什么我需要在我的主 app.get 块中设置标题?
采纳答案by Dobes Vandermeer
To answer your main question, the CORS spec only requires the OPTIONS call to precede the POST or GET if the POST or GET has any non-simple content or headers in it.
要回答您的主要问题,如果 POST 或 GET 包含任何非简单内容或标题,则 CORS 规范仅需要在 POST 或 GET 之前调用 OPTIONS 。
Content-Types that require a CORS pre-flight request (the OPTIONS call) are any Content-Type except the following:
需要 CORS 飞行前请求(OPTIONS 调用)的内容类型是除以下内容之外的任何内容类型:
application/x-www-form-urlencodedmultipart/form-datatext/plain
application/x-www-form-urlencodedmultipart/form-datatext/plain
Any other Content-Types apart from those listed above will trigger a pre-flight request.
除了上面列出的内容类型之外的任何其他内容类型都将触发飞行前请求。
As for Headers, any Request Headers apart from the followingwill trigger a pre-flight request:
至于 Headers,除了以下的任何 Request Headers都会触发一个 pre-flight 请求:
AcceptAccept-LanguageContent-LanguageContent-TypeDPRSave-DataViewport-WidthWidth
AcceptAccept-LanguageContent-LanguageContent-TypeDPRSave-DataViewport-WidthWidth
Any other Request Headers will trigger the pre-flight request.
任何其他请求标头都将触发飞行前请求。
So, you could add a custom header such as: x-Trigger: CORS, and that should trigger the pre-flight request and hit the OPTIONS block.
因此,您可以添加一个自定义标头,例如: x-Trigger: CORS,这应该会触发飞行前请求并点击 OPTIONS 块。
回答by Wayne Maurer
I found the easiest way is to use the node.js package cors. The simplest usage is:
我发现最简单的方法是使用 node.js 包cors。最简单的用法是:
var cors = require('cors')
var app = express()
app.use(cors())
There are, of course many ways to configure the behaviour to your needs; the page linked above shows a number of examples.
当然,有很多方法可以根据您的需要配置行为;上面链接的页面显示了许多示例。
回答by evilcelery
Try passing control to the next matching route. If Express is matching app.get route first, then it won't continue onto the options route unless you do this (note use of next):
尝试将控制权传递给下一个匹配的路由。如果 Express 首先匹配 app.get 路由,则除非您这样做(注意使用 next),否则它将不会继续到 options 路由:
app.get('somethingelse', function(req, res, next) {
//..set headers etc.
next();
});
In terms of organising the CORS stuff, I put it in a middleware which is working well for me:
在组织 CORS 的东西方面,我把它放在一个对我来说效果很好的中间件中:
//CORS middleware
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'example.com');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
//...
app.configure(function() {
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'cool beans' }));
app.use(express.methodOverride());
app.use(allowCrossDomain);
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
回答by Lialon
To stay in the same idea of routing. I use this code :
保持相同的路由思想。我使用这个代码:
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
Similar to http://enable-cors.org/server_expressjs.htmlexample
回答by Yatender Singh
do
做
npm install cors --save
and just add these lines in your main file where your request going (keep it before any route).
并将这些行添加到您的请求所在的主文件中(将其保留在任何路由之前)。
const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors());
回答by mcfedr
I have made a more complete middleware suitable for express or connect. It supports OPTIONSrequests for preflight checking. Note that it will allow CORS access to anything, you might want to put in some checks if you want to limit access.
我做了一个更完整的中间件,适用于 express 或 connect。它支持OPTIONS预检检查请求。请注意,它将允许 CORS 访问任何内容,如果您想限制访问,您可能需要进行一些检查。
app.use(function(req, res, next) {
var oneof = false;
if(req.headers.origin) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
oneof = true;
}
if(req.headers['access-control-request-method']) {
res.header('Access-Control-Allow-Methods', req.headers['access-control-request-method']);
oneof = true;
}
if(req.headers['access-control-request-headers']) {
res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
oneof = true;
}
if(oneof) {
res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
}
// intercept OPTIONS method
if (oneof && req.method == 'OPTIONS') {
res.send(200);
}
else {
next();
}
});
回答by rahuL islam
install cors module of expressjs. you can follow these steps >
安装 expressjs 的 cors 模块。您可以按照以下步骤操作 >
Installation
安装
npm install cors
Simple Usage (Enable All CORS Requests)
简单使用(启用所有 CORS 请求)
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
for more details go to https://github.com/expressjs/cors
有关更多详细信息,请访问https://github.com/expressjs/cors
回答by Russ
Do something like this:
做这样的事情:
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();
});
回答by Reneesh TK
first simply install cors in your project.
Take terminal(command prompt) and cdto your project directory and run the below command:
首先简单地在你的项目中安装 cors。将终端(命令提示符)cd带到您的项目目录并运行以下命令:
npm install cors --save
Then take the server.js file and change the code to add the following in it:
然后获取 server.js 文件并更改代码以在其中添加以下内容:
var cors = require('cors');
var app = express();
app.use(cors());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'DELETE, PUT, GET, POST');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
This worked for me..
这对我有用..
回答by Daniel Laurindo
Testing done with express + node + ionic running in differente ports.
使用在不同端口中运行的 express + node + ionic 完成的测试。
Localhost:8100
Localhost:8100
Localhost:5000
Localhost:5000
// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});

