javascript - fetch() 无法设置从服务器接收到的 cookie?

标签 javascript node.js express cookies session-cookies

我正在使用 Express.js 服务器。使用 cookie-parser 我打开了这个端点

app.get("/s", (req,res) => {
    res.cookie("bsaSession", req.session.id)
    res.send("set cookie ok")
})

当我手动使用浏览器访问 http://localhost:5555/s 时,我的网站正在运行,浏览器调试控制台显示已应用 cookie。

enter image description here

但是当我使用 fetch API 执行等效操作时,它不会设置 cookie。

  async trySetCookie()
  {
    await fetch("http://localhost:5555/s",{
       method: 'GET',
       credentials: 'same-origin'
    })
  }

为什么?

最佳答案

我找到了解决方案。这个问题的核心是我的按钮触发 fetchhttp://localhost:3000/ .服务器在http://localhost:5555/ (我是在自己的机器上模拟真实环境)

问题是这个 fetch打电话

  async trySetCookie()
  {
    await fetch("http://localhost:5555/s",{
       method: 'GET',
       credentials: 'same-origin'
    })
  }

没有credentials , 浏览器无法通过 fetch 发送或接收 cookie ( https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials )

credentials作为same-origin我可以在 Set-Cookie 中看到来自服务器的 cookie响应 header ,但浏览器中没有存储任何内容。一件奇怪的事情是这个响应总是有 HttpOnly不管我的 {httpOnly : true/false} 是在 cookie 字符串之后标记的服务器上的设置。在手动使用浏览器对页面做GET请求的情况下,HttpOnly像往常一样受到尊重,并且设置了 cookie。

所以解决方案是设置credentials作为include允许跨源 cookie 发送。

  async trySetCookie()
  {
    await fetch("http://localhost:5555/s",{
       method: 'GET',
       credentials: 'include'
    })
  }

此外,在服务器端,您需要使用新 header 手动允许特定来源:

app.get("/s", (req,res) => {
    res.cookie("bsaSession", req.session.id, {httpOnly:false})
    res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
    res.header('Access-Control-Allow-Credentials','true'
    res.send("set")
})

不这样做会导致

XMLHttpRequest cannot load http://localhost:5555/s. Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.

但是不管这个错误,cookie 都会被设置。仍然很高兴包含该 header 以消除错误。

如果您使用 cors Express 的中间件它甚至更容易。您可以只使用这些选项

var corsOptions = {
  origin: 'http://localhost:3000',
  credentials:  true
}

app.use(cors(corsOptions))

当然还有credentials: 'include'客户端仍然需要。

关于javascript - fetch() 无法设置从服务器接收到的 cookie?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42710057/

相关文章:

javascript - 在对象数组中查找数据数组

javascript - 重复javascript计算并显示到表格

node.js - 如何将Web Stream转换为NodeJS原生Stream

javascript - 带 app.use 的 multer 配置返回 TypeError

node.js - 方法 "collection.find()"最多接受两个参数

javascript - Django 在 POST 请求后不呈现

javascript - 如何将元素的背景图像设置为用户上传的图像

javascript - pdfkit (Expressjs-Nodejs) 中的 HTML 表格

node.js - express.js - req.body?

javascript - 如何在 Node.js 中从不同的应用程序注入(inject)模块