React fetch,"凭证:包含",破坏了我的整个请求,我得到了一个错误



摘要:

我正在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. 为什么我需要包括";凭证";如果没有它就行吗?因为如果我不包括";凭证";当fetch请求正确执行时,会话cookie将不会从我的客户端发送到服务器,除非我包含credentials: "include"。如果我删除了所有的头并包含mode: 'no-cors',那么会执行fetch请求,并将会话cookie发送到服务器,但显然我得到了一个不透明的响应,无论如何我都需要使用cors

尝试次数:


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

以下是我尝试过的一些不起作用的东西:

  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发送回服务器,但这是我必须实现的另一个解决方案的原因。

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

TLDR:


只要我不包括credentials: "include",我的飞行前请求就会通过,但会话cookie不会通过。

当我包含credentials: "include"mode: 'no-cors'时,会话cookie会被传递,但是,我收到了一个不透明的响应,我需要使用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'.

这很可能来自您的服务器。你在后端安装了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文档,

当响应认证请求时,服务器必须在访问控制允许原点标头的值中指定原点,而不是指定"*"通配符。

此外,如果您已经使用npm-cors模块来处理设置响应标头,请注意

默认配置相当于:

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

所以你必须明确地配置它。这就是@yeeeehaw的答案奏效的原因——他们建议明确地设置origin选项,这转化为在幕后设置Access-Control-Allow-Origin

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

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

origin: true

在Stack Overflow上,这里也有描述,在反向代理级别上(对于NGINX(也有描述。也许最相似的问题就在这里。

如果你想接受来自多个不同域的请求,你也可以这样做:

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

相关内容

最新更新