如何独立于 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秒(除了浏览器自动设置的)不超过AcceptAccept-LanguageContent-LanguageContent-Type.
  • Content-Type 只能是 application/x-www-form-urlencodedmultipart/form-datatext/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();
});