Javascript fetch 未发送 Cookie Header (CORS)
Javascript fetch is not sending Cookie Header (CORS)
我正在尝试将 Cookie 发送到 javascript 提取 CORS 请求中的 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脚本设置如下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 Header 没有随请求一起发送。我也试过:
let headers = new Headers();
headers.set('Cookie', document.cookie);
那也没有效果。我到底做错了什么?
我检查了开发工具中的网络选项卡。 PHP 脚本中的 $_COOKIE
也是空的。绝对没有错误。我还可以看到 Cookie Header 是在任何非 CORS fetch
请求中发送的。
编辑:这是其中一个 Cookie 的设置:
Name: PHPSESSID
Path: /
Secure: true
SameSite: none
我无法共享域,因为它不是 public。但是 Cookie 域与请求中的来源具有相同的值 Header(减去 https://)。
编辑 2:更改了提取 URL 以使发生的事情更清楚。
在 CORS 模式下,通常不应将 Cookie 附加到预检请求。你可能想看看这个。
Note: Browsers should not send credentials in preflight requests irrespective of this setting. For more information see: CORS > Requests with credentials.
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
问题
请注意,取决于
- cookie 的
Path
属性值,
- cookie 的
Domain
属性的有效值,
- cookie 的
Secure
属性值,
- cookie的有效值
SameSite
attribute,
- 请求的发出和目标来源,
cookie 可能附加也可能不附加到请求。与您的案例特别相关的是 Domain
属性;查看 MDN's page on the topic:
The Domain
attribute specifies which hosts can receive a cookie. If unspecified, the attribute defaults to the same host that set the cookie, excluding subdomains. If Domain
is specified, then subdomains are always included. Therefore, specifying Domain
is less restrictive than omitting it. However, it can be helpful when subdomains need to share information about a user.
您在源 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
发送 cookie
Fetch standard specifies a list of forbidden header names; Cookie
is one of them. You cannot set a header named Cookie
on a request sent with fetch
; the standard simply forbids it. If you want to attach existing cookies to a cross-origin request, use the 'include'
value for the credentials
parameter 传入 fetch
选项。
我正在尝试将 Cookie 发送到 javascript 提取 CORS 请求中的 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脚本设置如下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 Header 没有随请求一起发送。我也试过:
let headers = new Headers();
headers.set('Cookie', document.cookie);
那也没有效果。我到底做错了什么?
我检查了开发工具中的网络选项卡。 PHP 脚本中的 $_COOKIE
也是空的。绝对没有错误。我还可以看到 Cookie Header 是在任何非 CORS fetch
请求中发送的。
编辑:这是其中一个 Cookie 的设置:
Name: PHPSESSID
Path: /
Secure: true
SameSite: none
我无法共享域,因为它不是 public。但是 Cookie 域与请求中的来源具有相同的值 Header(减去 https://)。
编辑 2:更改了提取 URL 以使发生的事情更清楚。
在 CORS 模式下,通常不应将 Cookie 附加到预检请求。你可能想看看这个。
Note: Browsers should not send credentials in preflight requests irrespective of this setting. For more information see: CORS > Requests with credentials.
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
问题
请注意,取决于
- cookie 的
Path
属性值, - cookie 的
Domain
属性的有效值, - cookie 的
Secure
属性值, - cookie的有效值
SameSite
attribute, - 请求的发出和目标来源,
cookie 可能附加也可能不附加到请求。与您的案例特别相关的是 Domain
属性;查看 MDN's page on the topic:
The
Domain
attribute specifies which hosts can receive a cookie. If unspecified, the attribute defaults to the same host that set the cookie, excluding subdomains. IfDomain
is specified, then subdomains are always included. Therefore, specifyingDomain
is less restrictive than omitting it. However, it can be helpful when subdomains need to share information about a user.
您在源 https://sub1.example.com
:
Set-Cookie: PHPSESSID=whatever; Path=/; SameSite=None; Secure
因此,该 cookie 将附加到目标来源为 https://sub1.example.com
的(经过认证的)请求,而不会附加到其他请求。
解决方案
如果您希望将您的 cookie 发送到域为 example.com
子域的所有安全来源,您需要将其 Domain
显式设置为 example.com
。
关于使用 fetch
发送 cookie
Fetch standard specifies a list of forbidden header names; Cookie
is one of them. You cannot set a header named Cookie
on a request sent with fetch
; the standard simply forbids it. If you want to attach existing cookies to a cross-origin request, use the 'include'
value for the credentials
parameter 传入 fetch
选项。