如何独立于 CORS 中间件解决 NodeJS 中的 CORS 错误
How to solve CORS error in NodeJS independent of CORS middleware
我在尝试从客户端向节点服务器发出请求时遇到 CORS 错误。我想解决独立于 CORS 中间件的问题。这是服务器端代码。如果我遗漏了什么,请告诉我。谢谢
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT");
res.setHeader("Access-Control-Allow-Headers", "application/json");
res.send("<h1>Server is running at port 3000!<h1>");
});
app.listen(3000);
控制台报错:
Access to fetch at 'http://localhost:3000/' from origin 'http://127.0.0.1:5500' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
您在控制台上收到的错误消息是这样说的:
Response to preflight request doesn't pass access control check
这意味着您发送的请求类型不是“简单”请求,需要服务器 pre-flight。 Pre-flight 是浏览器发送 OPTIONS 请求的地方,其中包含有关它要发送的请求类型的一些详细信息。然后,服务器必须使用正确的 COR 信息响应该 OPTIONS 请求,然后浏览器才会将该请求视为已批准并发送实际请求。
要响应 pre-flight 请求,您必须处理传入的 OPTIONS 请求(不是 GET 或 POST 或 PUT,而是 OPTIONS)。这是浏览器询问您的服务器是否可以发送此请求。您可以阅读更多关于 pre-flight 请求 here on MDN. And, you can read about the difference between simple requests and pre-flighted requests here on MDN.
要对您的服务器进行编码以接受 pre-flighted 请求,您可以这样做:
app.options("/", (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT");
res.setHeader("Access-Control-Allow-Headers": "Content-Type");
res.sendStatus(204);
});
根据 pre-flighted 请求的具体内容(content-type、方法等),您可能需要在此处指定其他选项。您没有在此处显示相关请求的代码,因此我们无法提供有关该请求的更多具体细节。
还有,你有这个:
res.setHeader("Access-Control-Allow-Headers", "application/json");
这没有什么意义,因为“application/json”是 content-type,而不是 header。也许你的意思是:
res.setHeader("Access-Control-Allow-Headers": "Content-Type");
简单请求
上述 MDN 参考资料中均有详细说明,但不需要 COR pre-flight 的简单请求满足以下条件:
- Http 方法是 GET、HEAD 或 POST
- 请求中手动设置的header秒(除了浏览器自动设置的)不超过
Accept
、Accept-Language
、Content-Language
和Content-Type
.
- Content-Type 只能是
application/x-www-form-urlencoded
、multipart/form-data
或 text/plain
任何不符合这些简单规则的请求都需要 pre-flight。因此,例如,如果您将 Content-Type
设置为 application/json
,那将立即导致 pre-flight,因为这不是 non-preflighted 允许的 content-type 之一要求。如果您的请求是 GET,则根本不需要设置 content-type,因为您没有随请求发送任何内容。
const corsOpts = {
origin: '*',
methods: [
'GET',
'POST',
],
allowedHeaders: [
'Content-Type',
],
};
app.use(cors(corsOpts));
OR you can use
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
我在尝试从客户端向节点服务器发出请求时遇到 CORS 错误。我想解决独立于 CORS 中间件的问题。这是服务器端代码。如果我遗漏了什么,请告诉我。谢谢
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT");
res.setHeader("Access-Control-Allow-Headers", "application/json");
res.send("<h1>Server is running at port 3000!<h1>");
});
app.listen(3000);
控制台报错:
Access to fetch at 'http://localhost:3000/' from origin 'http://127.0.0.1:5500' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
您在控制台上收到的错误消息是这样说的:
Response to preflight request doesn't pass access control check
这意味着您发送的请求类型不是“简单”请求,需要服务器 pre-flight。 Pre-flight 是浏览器发送 OPTIONS 请求的地方,其中包含有关它要发送的请求类型的一些详细信息。然后,服务器必须使用正确的 COR 信息响应该 OPTIONS 请求,然后浏览器才会将该请求视为已批准并发送实际请求。
要响应 pre-flight 请求,您必须处理传入的 OPTIONS 请求(不是 GET 或 POST 或 PUT,而是 OPTIONS)。这是浏览器询问您的服务器是否可以发送此请求。您可以阅读更多关于 pre-flight 请求 here on MDN. And, you can read about the difference between simple requests and pre-flighted requests here on MDN.
要对您的服务器进行编码以接受 pre-flighted 请求,您可以这样做:
app.options("/", (req, res) => {
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT");
res.setHeader("Access-Control-Allow-Headers": "Content-Type");
res.sendStatus(204);
});
根据 pre-flighted 请求的具体内容(content-type、方法等),您可能需要在此处指定其他选项。您没有在此处显示相关请求的代码,因此我们无法提供有关该请求的更多具体细节。
还有,你有这个:
res.setHeader("Access-Control-Allow-Headers", "application/json");
这没有什么意义,因为“application/json”是 content-type,而不是 header。也许你的意思是:
res.setHeader("Access-Control-Allow-Headers": "Content-Type");
简单请求
上述 MDN 参考资料中均有详细说明,但不需要 COR pre-flight 的简单请求满足以下条件:
- Http 方法是 GET、HEAD 或 POST
- 请求中手动设置的header秒(除了浏览器自动设置的)不超过
Accept
、Accept-Language
、Content-Language
和Content-Type
. - Content-Type 只能是
application/x-www-form-urlencoded
、multipart/form-data
或text/plain
任何不符合这些简单规则的请求都需要 pre-flight。因此,例如,如果您将 Content-Type
设置为 application/json
,那将立即导致 pre-flight,因为这不是 non-preflighted 允许的 content-type 之一要求。如果您的请求是 GET,则根本不需要设置 content-type,因为您没有随请求发送任何内容。
const corsOpts = {
origin: '*',
methods: [
'GET',
'POST',
],
allowedHeaders: [
'Content-Type',
],
};
app.use(cors(corsOpts));
OR you can use
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});