React fetch, “credentials: include”,破坏了我的整个请求,我得到一个错误

IT技术 javascript reactjs ajax api rest
2021-05-23 07:35:30

概括:

我正在 React 中向我的 Node.js 服务器执行获取请求。

每当我不包括credentials: "include"和 在我的获取请求中,请求就会成功地发送到服务器并返回给客户端。

但是,当我包含时credentials: "include",如下所示:

fetch('http://localhost:8000/',
    {   method: "GET", 
       'credentials': 'include',
        headers: new Headers({
            'Accept': 'application/json',
            'Access-Control-Allow-Origin':'http://localhost:3000/',
            'Content-Type': 'application/json',
    })

}) ....

我收到此预检错误:

login:1 Access to fetch at 'http://localhost:8000/' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

语境:


为什么我需要包括其中任何一个?

  1. 我认为很明显为什么我需要包含“标题”,我正在使用 cors,如果我不包含,'Access-Control-Allow-Origin':'http://localhost:3000/'那么服务器将不会接受请求。
  2. 如果没有它就可以工作,为什么我需要包含“凭据”?因为如果我在获取请求正确执行时不包含“凭据”,则会话 cookie 将不会从我的客户端发送到服务器,除非我包含credentials: "include". 如果我删除所有标头和 include mode: 'no-cors',则执行 fetch 请求并将会话 cookie 发送到服务器,但显然我得到了一个不透明的响应,无论如何我都需要使用 cors。

尝试:


有很多类似的堆栈溢出问题,但不准确,因此他们的解决方案不起作用。

以下是我尝试过的一些无效的方法:

  1. 这已经在我的服务器上,但有人建议在客户端尝试它,所以我做了: 'Access-Control-Request-Method': 'GET, POST, DELETE, PUT, OPTIONS',

  2. 'Access-Control-Allow-Credentials': 'true',

  3. 'withCredentials': 'true',

  4. Origin: 'http://localhost:3000/auth',

  5. crossorigin: true,

  6. 是的,我已经设置了一个代理(这有助于解决先前的问题),如下所示: "proxy": "http://localhost:8000"

  7. 我尝试了更多其他解决方案但无济于事,我确信我已经阅读了(如果不是全部)与此问题相关的绝大多数问题以及相应的答案。我的服务器设置正确,这就是为什么我没有包含任何代码。

在理想情况下,我不需要使用credentials: "include"会话 cookie 将其发送回我的服务器,但这是我必须实施的另一个解决方案的原因。

如果有人能帮助我,我将不胜感激。

域名注册地址:


每当我不包含时credentials: "include"我的预检请求都会通过,但不会通过会话 cookie。

当我不包括会话cookie被传递credentials: "include"mode: 'no-cors',不过,我收到一个不透明的react,我需要使用CORS。

最后,当我将两者(cors 和凭据)结合起来时,我的预检请求失败并出现以下错误:

login:1 Access to fetch at 'http://localhost:8000/' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

3个回答

这很可能来自您的服务器。您是否在后端安装了 cors npm 包?

https://www.npmjs.com/package/cors

您还需要对其进行配置。

最有可能在您的 index.js 文件中。

const express = require("express")
const cors = require("cors");
const app = express();

app.use(cors({
  origin : http://localhost:3000 (Whatever your frontend url is) 
  credentials: true, // <= Accept credentials (cookies) sent by the client
})

app.use("/api/whatever/the/endpoint", yourRouter);

这必须在任何路线之前设置。Origin 可以是一组列入白名单(允许)的域,用于与您的后端 api 进行通信。

这里的正确解释是服务器Access-Control-Allow-Origin: *在响应中发回了标头(如错误消息中所述)。

没有凭据这是可以接受的。但是,引用Mozilla CORS 文档

在响应有凭据的请求时,服务器必须在 Access-Control-Allow-Origin 标头的值中指定一个来源,而不是指定“*”通配符。

此外,如果您已经在使用npm cors module来处理设置响应头,请注意

默认配置相当于:

{
  "origin": "*",
  "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
  "preflightContinue": false,
  "optionsSuccessStatus": 204
}

所以你必须明确配置它。这就是@yeeeehaw 的回答有效的原因 - 他们建议明确设置origin转换为Access-Control-Allow-Origin幕后设置的选项

请注意,作为替代解决方案,您可以将请求的来源反映为其值,而不是显式设置origin(即Access-Control-Allow-Origin中间件方便地通过它的配置提供了这一点。cors

Boolean - 将 origin 设置为 true 以反映请求来源,如 req.header('Origin') 所定义,或将其设置为 false 以禁用 CORS。

origin: true

在堆栈溢出这也说明了这里,并在反向代理级别在这里(为NGINX)。也许最相似的问题是here

如果您想接受来自多个不同域的请求,您也可以执行以下操作:

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', req.headers.origin);
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  next();
});

如此处所述:https : //www.zigpoll.com/blog/cors-with-express-and-fetch