【问题标题】:Javascript fetch is not sending Cookie Header (CORS)Javascript 获取未发送 Cookie 标头 (CORS)
【发布时间】:2022-01-05 20:52:00
【问题描述】:

我正在尝试在 javascript 获取 CORS 请求中将 Cookie 发送到 PHP 脚本。请求从https://sub1.example.com 开始,包含以下选项:

let response = await fetch('https://sub2.example.com/target.php', {
    method: "POST",
    headers: headers,
    body: formData,
    mode: 'cors',
    credentials: 'include',
    cache: 'no-store'
});

相应的 PHP Script 设置以下 Headers:

header('Access-Control-Allow-Origin: https://www.example.com');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, X-Request-With, Set-Cookie, Cookie, Bearer');

但是 Cookie 标头没有随请求一起发送。我也试过了:

let headers = new Headers();
headers.set('Cookie', document.cookie);

这也没有效果。我到底做错了什么?

我检查了开发工具中的网络选项卡。 PHP 脚本中的 $_COOKIE 也是空的。绝对没有错误。我还可以看到 Cookie 标头是在任何非 CORS fetch 请求中发送的。

编辑:以下是其中一个 Cookie 的设置:

Name: PHPSESSID
Path: /
Secure: true
SameSite: none

我无法共享域,因为它不是公开的。但是 Cookie 域与请求标头中的 Origin 具有相同的值(减去 https://)。

编辑 2:更改了获取 URL 以更清楚地了解正在发生的事情。

【问题讨论】:

  • Cookie Header is not send...你怎么知道?目前尚不清楚您测试了什么,或者您看到了什么后果。有错误吗?
  • 我检查了开发工具中的网络选项卡。 PHP 脚本中的 $_COOKIE 也是空的。绝对没有错误。我还可以看到,Cookie 标头是在无 CORS 获取请求中发送的。
  • 请编辑您的问题并添加相关cookie的NameDomainPathSecureSameSite属性值。
  • @jub0bs 我已经编辑了问题。
  • @KHansen 嗯,有答案。浏览器永远不会向sub2.example.com 发送Domain 属性的有效值为sub1.example.com 的cookie。如果您希望将 cookie 发送到子域,则需要将其 Domain 属性显式设置为公共父域,例如example.com。见developer.mozilla.org/en-US/docs/Web/HTTP/…

标签: javascript cookies attributes fetch


【解决方案1】:

问题

请注意,这取决于

  • cookie 的Path 属性的值,
  • cookie 的Domain 属性的有效值,
  • cookie 的Secure 属性的值,
  • cookie的SameSite attribute的有效值,
  • 请求的发出和目的地来源,

cookie 可能会或可能不会附加到请求中。与您的案例特别相关的是 Domain 属性;查看MDN's page on the topic:

Domain 属性指定哪些主机可以接收 cookie。如果未指定,则该属性默认为设置 cookie 的同一主机,不包括子域。如果指定了Domain ,则始终包含子域。因此,指定Domain 比省略它的限制要小。但是,当子域需要共享有关用户的信息时,它会很有帮助。

您在来源https://sub1.example.com 上按如下方式设置cookie:

Set-Cookie: PHPSESSID=whatever; Path=/; SameSite=None; Secure

因此,该 cookie 将附加到目标来源为 https://sub1.example.com 的(有凭据的)请求,而不是其他请求。

解决方案

如果您希望将您的 cookie 发送到其域为 example.com 子域的所有安全源,您需要将其 Domain 显式设置为 example.com


关于用fetch发送cookies

Fetch standard 指定forbidden header names 的列表; Cookie 就是其中之一。您不能在使用fetch 发送的请求上设置名为Cookie 的标头;标准只是forbids it。如果要将现有 cookie 附加到跨域请求,请使用 fetch 选项中传递的 'include' value for the credentials parameter

【讨论】:

  • @KHansen — 您正在尝试使用 code 设置 Cookies 标头,而不是通过较早的请求将 cookie previously set 发送到 表单动作的来源document.cookie 是 HTML 文档的来源,而不是动作的来源)。
  • @Quentin 不,这只是我也尝试过的。在我的获取请求中设置了credentials: 'include。那应该发送 Cookie 标头,但它没有。
【解决方案2】:

Cookie 通常不应该附加到 CORS 模式下的预检请求。你可能想看看这个。

注意:无论此设置如何,浏览器都不应在预检请求中发送凭据。有关详细信息,请参阅:CORS > 带有凭据的请求。

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

【讨论】:

  • 我并不真正关心预检请求。我需要 POST 请求中的 Cookie 数据。
  • cookie是如何设置的?只有https吗?什么是 cookie 域,它与您从中获取的脚本相同吗?
  • Cookie 具有以下设置:SameSite:无/安全:true。域是一样的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-03
  • 2023-04-09
  • 2021-05-29
  • 2014-08-02
  • 2021-01-08
  • 2018-01-05
  • 2017-08-01
相关资源
最近更新 更多