【问题标题】:How to solve CORS error in NodeJS independent of CORS middleware如何解决独立于 CORS 中间件的 NodeJS 中的 CORS 错误
【发布时间】:2022-01-15 18:29:12
【问题描述】:

我在尝试从客户端向节点服务器发出请求时遇到 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);

控制台报错:

CORS 策略已阻止从源“http://127.0.0.1:5500”获取“http://localhost:3000/”的访问权限:对预检请求的响应未通过访问控制检查:否请求的资源上存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

【问题讨论】:

  • 请问我的问题有什么问题????
  • 为什么要在没有中间件的情况下解决?
  • 我只是想知道如何手动操作。

标签: node.js cors


【解决方案1】:

您在控制台上收到的错误消息是这样的:

对预检请求的响应未通过访问控制检查

这意味着您发送的请求类型不是“简单”请求,需要服务器预检。 Pre-flight 是浏览器发送 OPTIONS 请求的地方,其中包含有关它要发送的请求类型的一些详细信息。然后,服务器必须使用正确的 COR 信息响应该 OPTIONS 请求,然后浏览器才会将该请求视为已批准并发送实际请求。

要响应飞行前请求,您必须处理传入的 OPTIONS 请求(不是 GET 或 POST 或 PUT,而是 OPTIONS)。这是浏览器询问您的服务器是否可以发送此请求。您可以阅读更多关于飞行前请求here on MDN。并且,您可以阅读有关简单请求和预发送请求之间的区别here on MDN

要对您的服务器进行编码以接受预先发送的请求,您可以执行以下操作:

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);
});

根据预发送请求的具体内容(内容类型、方法等),您可能需要在此处指定其他选项。您没有在此处显示相关请求的代码,因此我们无法提供有关该请求的更具体的详细信息。

另外,你有这个:

res.setHeader("Access-Control-Allow-Headers", "application/json");

这实际上没有意义,因为“application/json”是一种内容类型,而不是标题。也许你的意思是:

res.setHeader("Access-Control-Allow-Headers": "Content-Type");

简单请求

这在上述 MDN 参考文献之一中都有详细说明,但一个不需要 COR 飞行前的简单请求符合以下标准:

  • Http 方法是 GET、HEAD 或 POST
  • 手动设置的请求头(除了浏览器自动设置的)不超过AcceptAccept-LanguageContent-LanguageContent-Type
  • Content-Type 只能是application/x-www-form-urlencodedmultipart/form-datatext/plain

任何不符合这些简单规则的请求都需要进行飞行前处理。因此,例如,如果您将 Content-Type 设置为 application/json,这将立即导致预检,因为这不是未预检请求的允许内容类型之一。如果您的请求是 GET,则根本不需要设置 content-type,因为您没有随请求发送任何内容。

【讨论】:

    【解决方案2】:
    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();
    });
    

    【讨论】:

      猜你喜欢
      • 2020-12-18
      • 2021-05-28
      • 2021-09-15
      • 2021-09-27
      • 2021-07-25
      • 2021-09-12
      • 2021-01-14
      • 2020-12-18
      • 1970-01-01
      相关资源
      最近更新 更多