为什么将 CORS 标头添加到 OPTIONS 路由不允许浏览器访问我的 API?
我正在尝试在使用 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'
# ...
它似乎不起作用。我的浏览器(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'
# ...
它有效(在 Chrome 中)。这也适用于 Safari。
我读过...
在实现 CORS 的浏览器中,每个跨源 GET 或 POST 请求之前都会有一个 OPTIONS 请求,用于检查 GET 或 POST 是否正常。
所以我的主要问题是,为什么我的情况似乎没有发生这种情况?为什么我的 app.options 块没有被调用?为什么我需要在主 app.get 块中设置标头?
I am trying to support CORS in my Node.js application that uses the Express.js web framework. I have read a Google group discussion about how to handle this, and read a few articles about how CORS works. First, I did this (code is written in CoffeeScript syntax):
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:
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.
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.
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
我发现最简单的方法是使用 node.js 包 cors。最简单的用法是:
当然有很多方法可以根据您的需要配置行为;上面链接的页面显示了许多示例。
I found the easiest way is to use the node.js package cors. The simplest usage is:
There are, of course many ways to configure the behaviour to your needs; the page linked above shows a number of examples.
尝试将控制权传递给下一个匹配的路由。如果 Express 首先匹配 app.get 路由,那么它不会继续到选项路由,除非你这样做(注意 next 的使用):
在组织 CORS 内容方面,我将其放入一个对我来说效果很好的中间件:
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):
In terms of organising the CORS stuff, I put it in a middleware which is working well for me:
为了回答您的主要问题,CORS 规范仅要求 OPTIONS 调用位于 POST 或 GET 之前(如果 POST 或 GET 中包含任何非简单内容或标头)。
需要 CORS 预检请求(OPTIONS 调用)的 Content-Type 是除以下内容之外的任何 Content-Type:
application/x-www-form-urlencoded
multipart/form-data
text/plain
除了上面列出的内容类型之外的任何其他内容类型都将触发预检请求。
至于标头,除了以下内容之外的任何请求标头都将触发预检请求:
Accept
Accept-Language
Content-Language
内容类型
DPR
保存数据
视口宽度
宽度
任何其他请求标头都会触发预检 要求。
因此,您可以添加一个自定义标头,例如:
x-Trigger: CORS
,这应该会触发飞行前请求并命中 OPTIONS 块。请参阅 MDN Web API 参考 - CORS 预检请求
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.
Content-Types that require a CORS pre-flight request (the OPTIONS call) are any Content-Type except the following:
application/x-www-form-urlencoded
multipart/form-data
text/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 following will trigger a pre-flight request:
Accept
Accept-Language
Content-Language
Content-Type
DPR
Save-Data
Viewport-Width
Width
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.See MDN Web API Reference - CORS Preflighted requests
保持相同的路由理念。我使用此代码:
类似于 http://enable-cors.org/server_expressjs.html 示例
To stay in the same idea of routing. I use this code :
Similar to http://enable-cors.org/server_expressjs.html example
执行
并将这些行添加到您的请求所在的主文件中(将其保留在任何路由之前)。
do
and just add these lines in your main file where your request going (keep it before any route).
我做了一个比较完整的中间件,适合express或者connect。它支持用于预检检查的
OPTIONS
请求。请注意,它将允许 CORS 访问任何内容,如果您想限制访问,您可能需要进行一些检查。I have made a more complete middleware suitable for express or connect. It supports
OPTIONS
requests 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.做这样的事情:
Do something like this:
安装expressjs的cors模块。您可以按照以下步骤操作>
安装
简单使用(启用所有 CORS 请求)
有关更多详细信息,请访问 https:// github.com/expressjs/cors
install cors module of expressjs. you can follow these steps >
Installation
Simple Usage (Enable All CORS Requests)
for more details go to https://github.com/expressjs/cors
使用在不同端口运行的 Express + Node + ionic 完成测试。
本地主机:8100
本地主机:5000
Testing done with express + node + ionic running in differente ports.
Localhost:8100
Localhost:5000
首先只需在您的项目中安装 cors 即可。
使用终端(命令提示符)和 cd 到您的项目目录并运行以下命令:
然后获取 server.js 文件并更改代码以在其中添加以下内容:
这对我有用..
first simply install cors in your project.
Take terminal(command prompt) and
cd
to your project directory and run the below command:Then take the server.js file and change the code to add the following in it:
This worked for me..
前段时间,我遇到了这个问题,所以我这样做是为了在我的nodejs应用程序中允许CORS:
首先,您需要使用以下命令安装
cors
:现在添加将以下代码添加到您的应用程序启动文件中,例如(
app.js 或 server.js
)Some time ago, I faced this problem so I did this to allow CORS in my nodejs app:
First you need to install
cors
by using below command :Now add the following code to your app starting file like (
app.js or server.js
)这对我有用,因为它在路线内很容易实现,我使用meanjs并且它工作正常,safari,chrome等。
This works for me, as its an easy implementation inside the routes, im using meanjs and its working fine, safari, chrome, etc.
如果您想让它特定于控制器,您可以使用:
请注意,这也将允许 iframe。
If you want to make it controller specific, you can use:
Please note that this will also allow iframes.
在我的
index.js
中我添加了:In my
index.js
I added:cors
包是解决 express.js 中 CORS 策略问题的推荐方法,但您还需要确保为app.options
启用它,如下所示:cors
package is recommended way to for solving the CORS policy issue in express.js, but you also need to make sure to enable it forapp.options
as well, like below:可以参考下面的代码进行同样的操作。来源:Academind/node-restful-api
Can refer the code below for the same. Source: Academind/node-restful-api
最简单的答案是仅使用 cors 包。
这将全面启用 CORS。如果您想了解如何在没有外部模块的情况下启用 CORS,您真正需要的是一些设置 Express 中间件 href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin" rel="noreferrer">'Access-Control-Allow-Origin'标头< /a>.这是允许从浏览器到服务器的交叉请求域所需的最低限度。
The easiest answer is to just use the cors package.
That will enable CORS across the board. If you want to learn how to enable CORS without outside modules, all you really need is some Express middleware that sets the 'Access-Control-Allow-Origin' header. That's the minimum you need to allow cross-request domains from a browser to your server.
我使用 Express 4.2.0 的最简单的解决方案(编辑:似乎在 4.3.0 中不起作用)是:
我想执行
app.all('/result', ...)
也会起作用...My simplest solution with Express 4.2.0 (EDIT: Doesn't seem to work in 4.3.0) was:
I suppose doing
app.all('/result', ...)
would work too...以下对我有用,希望对某人有帮助!
从 https://expressjs.com/en/resources/middleware 获取参考/cors.html#configuring-cors
Below worked for me, hope it helps someone!
Got reference from https://expressjs.com/en/resources/middleware/cors.html#configuring-cors
在你的主 js 文件中尝试这个:
这应该可以解决你的问题
Try this in your main js file:
This should solve your problem
使用 CORS 包。并输入此参数:
using
CORS
package. and put this parameters:如果你想让 CORS 在没有 cors NPM 包的情况下工作(为了纯粹的学习乐趣!),你绝对可以自己处理 OPTIONS 调用。这对我有用:
又好又简单,对吧?请注意使用 res.writeHead() 而不是我不熟悉的 res.header()。
If you want to get CORS working without the cors NPM package (for the pure joy of learning!), you can definitely handle OPTIONS calls yourself. Here's what worked for me:
Nice and simple, right? Notice the use of res.writeHead() instead of res.header(), which I am unfamiliar with.
在typescript中,如果你想使用node.js包 cors
如果你不想要使用第三方库进行 cors 错误处理,您需要更改handleCORSErrors() 方法。
用于使用 app.ts 文件
In typescript, if you want to use the node.js package cors
If you don't want to use third part libraries for cors error handling, you need to change the handleCORSErrors() method.
For using the app.ts file
使用 Express 中间件对我来说非常有用。如果您已经在使用 Express,只需添加以下中间件规则即可。它应该开始工作。
参考
Using Express Middleware works great for me. If you are already using Express, just add the following middleware rules. It should start working.
Reference
如果您的 Express 服务器启用了授权,您可以像这样实现
If your Express Server has Authorization enabled, you can achieve that like this
我发现使用 npm request 包(https://www.npmjs.com /package/request)
然后我的解决方案基于这篇文章 http://blog.javascripting.com/2015/01/17/dont-hassle-with-cors/
I found it to be extremely easy to do this with the npm request package (https://www.npmjs.com/package/request)
Then I based my solution on this post http://blog.javascripting.com/2015/01/17/dont-hassle-with-cors/
我对我的网络应用程序执行了以下步骤,并取得了成功:
将 cors 包添加到 Express:
在 bodyParser 配置之后添加以下行。我在 bodyParser 之前添加时遇到了一些麻烦:
I used the following steps to my web app and I had success:
Add the cors package to the express:
Add following lines after the bodyParser configuration. I had some troubles adding before bodyParser:
这与帕特的答案类似,不同之处在于我以 res.sendStatus(200); 结束。而不是下一个();
该代码将捕获方法类型 OPTIONS 的所有请求并发送回访问控制标头。
该代码按照问题中的要求接受来自所有来源的 CORS。但是,最好将 * 替换为特定来源,即 http://localhost:8080 以防止误用。
由于我们使用 app.options-method 而不是 app.use-method,因此我们不需要进行此检查:
我们可以在其他一些答案中看到这一点。
我在这里找到了答案: http://johnzhang.io/options-request-in-express< /a>.
This is similiar to Pat's answer with the difference that I finish with res.sendStatus(200); instead of next();
The code will catch all the requests of the method type OPTIONS and send back access-control-headers.
The code accepts CORS from all origins as requested in the question. However, it would be better to replace the * with a specific origin i.e. http://localhost:8080 to prevent misuse.
Since we use the app.options-method instead of the app.use-method we don't need to make this check:
which we can see in some of the other answers.
I found the answer here: http://johnzhang.io/options-request-in-express.
最简单的方法是使用以下命令在项目中安装 cors 模块:
然后在服务器文件中使用以下命令导入它:
然后只需将其用作中间件,如下所示:
希望这会有所帮助!
The simplest approach is install the cors module in your project using:
Then in your server file import it using the following:
Then simply use it as a middleware like this:
Hope this helps!
简单即困难:
simple is hard: