【问题标题】:React fetch, “credentials: include”, breaks my entire request and I get an errorReact fetch,“credentials: include”,破坏了我的整个请求,我得到一个错误
【发布时间】:2020-11-30 17:49:43
【问题描述】:

总结:

我正在 React 中向我的 Node.js 服务器发出 fetch 请求。

只要我不包含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"。如果我删除所有标头并包含mode: 'no-cors',则执行获取请求并将会话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 发送回我的服务器,但这是我必须实施另一个解决方案的原因。

如果有人可以帮助我,我将非常感激。

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'.

【问题讨论】:

    标签: javascript reactjs ajax api rest


    【解决方案1】:

    这很可能来自您的服务器。 你有没有在后端安装 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 通信的白名单(允许)域的数组。

    【讨论】:

    • 我确实在后端安装和设置了 cors,但不像你那样做。我使用了 StackOverflow 上的各种技术,但只有你的技术有效。谢谢!
    【解决方案2】:

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

    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

    【讨论】:

      【解决方案3】:

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

      如果没有凭据,这是可以接受的。但是,引用Mozilla CORS documentation

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

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

      默认配置相当于:

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

      所以你必须明确地配置它。这就是 @yeeeehaw's answer 起作用的原因 - 他们建议明确设置 origin 选项,这会转化为在幕后设置 Access-Control-Allow-Origin

      请注意,作为替代解决方案,您可以将reflect the request's origin back 作为其值,而不是显式设置origin(即Access-Control-Allow-Origin)。 cors 中间件通过其配置方便地提供了这一点。

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

      origin: true
      

      在 Stack Overflow 上这也被描述为 here,在反向代理级别 here(对于 NGINX)。也许最相似的问题是here

      【讨论】:

        猜你喜欢
        • 2011-11-26
        • 2012-09-27
        • 1970-01-01
        • 1970-01-01
        • 2019-10-08
        • 2012-08-05
        • 2020-07-25
        • 2020-09-30
        • 1970-01-01
        相关资源
        最近更新 更多