Javascript withCredentials 对 Cookie 的影响

阅读(3929)

问题

在父域页面,向其子域发起一个异步请求(XHR 或 fetch),能否清除掉父域上的 Cookies?

答案

可以,但需要发起请求时由 js 设置 credentials 属性,且服务端返回时包含 “Access-Control-Allow-Credentials: true” 的 Header。

延伸1

跨域情况下,如果不设置 credentials,发起的请求不会带有 cookies;同理也会忽略服务端发回响应中的 Set-Cookie。

In addition, this flag is also used to indicate when cookies are to be
ignored in the response. The default is false. XMLHttpRequest from a
different domain cannot set cookie values for their own domain unless
withCredentials is set to true before making the request.
via: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials

“设置 credentials” 对 XHR 而言是设置 xhr.withCredentials = true,对 fetch 是设置 credentials: 'include'

XHR 设置 credentials 示例:

var xhr;

if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
    xhr = new ActiveXObject("Msxml2.XMLHTTP") || new ActiveXObject("Microsoft.XMLHTTP");
}

xhr.open('POST', 'http://kaifage.com/setcookie', true);
xhr.withCredentials = true;
xhr.send();

Fetch 设置 credentials 示例:

fetch("http://kaifage.com/setcookie", {
    method: "POST",
    credentials: 'include'
});

当然,跨域需要设置 Access-Control-Allow-Origin 的 CORS Header。

延伸2

跨域情况下,发起的请求带有 credentials,但服务端的回包没有 Access-Control-Allow-Credentials: true,浏览器控制台会报错提示,但 cookie 设置会成功。

控制台报错类似于:

Failed to load http://api.kaifage.com/: The value of the
'Access-Control-Allow-Credentials' header in the response is '' which
must be 'true' when the request's credentials mode is 'include'.
Origin 'http://kaifage.com' is therefore not allowed access.

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