将 CORS 模块添加到单个快速路线不起作用
Posted
技术标签:
【中文标题】将 CORS 模块添加到单个快速路线不起作用【英文标题】:Adding CORS module to a single express route not working 【发布时间】:2020-06-26 14:26:02 【问题描述】:如果我enable CORS for all routes,则来自前端 (https://localhost:3000
) 的请求有效并获得正确的请求标头。
const express = require('express');
const cors = require('cors');
var app = express();
app.use(cors());
app.post('/api/submitEmail', () => console.log('yay'));
如果我 enable CORS on the individual route,完全按照文档布局,我会在控制台中收到 CORS 错误
app.post('/api/submitEmail', cors(), () => console.log('booooo'));
错误:
Access to XMLHttpRequest at 'http://localhost:8000/api/submitEmail' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我错过了什么?
来自下面前端的整个请求
const api =
process.env.NODE_ENV === "development"
? "http://localhost:8000"
: MY_PROD_URL;
const user =
email
;
axios.post(`$api/api/submitEmail`, user ).then(res =>
setIsLoading(false);
setValidationMessage(res.data);
);
【问题讨论】:
【参考方案1】:我遇到了同样的问题,@jfriend00 的回答帮助了我。 您只需要包含 express 应用的初始选项:
app.options('/this_is_your_cors_route', cors())
然后你的 cors 路线将起作用:
app.post('/this_is_your_cors_route', cors(), (req, res) => );
以下是此问题的文档:https://github.com/expressjs/cors#enabling-cors-pre-flight
【讨论】:
【参考方案2】:您没有向我们展示实际请求的详细信息,但如果请求包含某些特殊条件,则浏览器会在发出 POST 之前尝试使用 OPTIONS 请求对请求进行预检。当您仅在 cors()
路由处理程序中插入 cors()
调用时,不会处理 OPTIONS 请求,并且如果此特定的跨源请求是触发 OPTIONS 预飞行的类型,那么因为您不处理它,请求将失败。
你可以通过添加这个来解决这个问题:
app.options('/api/submitEmail', cors(), (req, res) => res.send());
因为这将处理该特定路线的 OPTIONS 飞行前。
您可以了解什么是“简单请求”here。除了简单请求之外的任何内容都需要 OPTIONS 飞行前。它可以像设置单个自定义标头或简单请求中不允许的内容类型一样简单,这将触发 OPTIONS 预检。
当您执行 app.use(cors());
时,它会自动为您处理飞行前的 OPTIONS 请求,因为所有 HTTP 动词都被发送到 app.use()
处理程序,并且 cors()
中间件处理程序支持为 OPTIONS 请求做正确的事情。
此外,在您的 POST 请求处理程序中,您需要发送响应,否则客户端只会坐在那里等待响应并最终超时。
【讨论】:
我将整个路线添加到原始问题中,看起来它不需要 OPTIONS 请求。 @user3521314 - 由发送者决定是否需要 OPTIONS 请求。显示发送代码。 哎呀,替换为来自前端的请求。 @user3521314 - 发送代码没有显示任何会触发 OPTIONS 请求的内容(尽管可能在其他地方设置了 axios 默认值导致它),但唯一确定的方法是检查Chrome 调试器中网络选项卡中的实际请求,并查看浏览器实际发送的内容。这还将向您显示它是否首先执行 OPTIONS 预检,并将向您显示浏览器从服务器接收的标头以及是否是您期望的所有内容。 @user3521314 = 嗯,我在您的详细错误消息中看到正在执行飞行前请求,并且在对飞行前请求的响应中没有获得正确的标头。你试过我的app.options()
建议了吗?以上是关于将 CORS 模块添加到单个快速路线不起作用的主要内容,如果未能解决你的问题,请参考以下文章