黑马程序员技术交流社区
标题:
谈谈Cookie
[打印本页]
作者:
天树123
时间:
2020-4-22 14:43
标题:
谈谈Cookie
一、前言
最近由于Chrome 80+对第三方cookie进行了限制,虽然没有像最新版的safari和Firefox一样默认禁止第三方cookie,但是离完全禁止第三方cookie也不远。但因此也给我们前端开发人员带来了一些影响,第三方cookie不能正常携带,造成了许多请求有问题。
二、cookie的用途
众所周知HTTP请求是无状态请求,简言之即是HTTP请求不知道请求是否是来自同一个客户端,对于仅是访问无需用户标识的静态资源这是没有问题,但是如果我们在天猫、或者淘宝上购买东西时,服务端无法知道请求是否来自同一个用户,这就很糟糕了。所以HTTP协议需要占用浏览器的一小块存储,存储当前访问用户的一些状态,然后每次发起HTTP请求,请求中就会携带这些状态,从而让服务器知道你是谁。cookie技术就是为了解决这个问题,让无状态的HTTP协议拥有一小块记忆。cookie是一小段数据文本,是服务端为了辨别用户身份而储存在用户本地终端上的加密数据。可分为内存cookie和硬盘cookie,内存cookie由浏览器自己维护,写在内存里,在浏览器关闭时,就消失了。对于设定了过期时间的cookie是硬盘cookie,会存储在文件内,除非用户手工清理或到了过期时间,否则cookie是一直存在的
三、设置cookie
cookie可以通过客户端的document.cookie方法进行设置,如下是MDN提供客户端的设置cookie的方法。
var docCookies = {
getItem: function (sKey) {
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
},
setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
var sExpires = "";
if (vEnd) {
switch (vEnd.constructor) {
case Number:
sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
break;
case String:
sExpires = "; expires=" + vEnd;
break;
case Date:
sExpires = "; expires=" + vEnd.toUTCString();
break;
}
}
document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
return true;
},
removeItem: function (sKey, sPath, sDomain) {
if (!sKey || !this.hasItem(sKey)) { return false; }
document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + ( sDomain ? "; domain=" + sDomain : "") + ( sPath ? "; path=" + sPath : "");
return true;
},
hasItem: function (sKey) {
return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
},
keys: /* optional method: you can safely remove it! */ function () {
var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
for (var nIdx = 0; nIdx < aKeys.length; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
return aKeys;
}
};
服务端也可以设置cookie,通过响应头的set-cookie进行cookie的设置。其中set-cookie的主要信息包含如下。
1、cookie-name=cookie-value:cookie的名/值对;
2、Expires=<date>[可选]:cookie的最长有效时间;
3、Max-Age=<non-zero-digit>[可选]:cookie失效之前需要经过的秒数,当Expires 和Max-Age均存在时,Max-Age优先级更高。;
4、Domain=<domain-value>[可选]:指定cookie的需要送达的域名,偌没有指定,那么默认值为当前访问地址中的主机部分(但是不包含子域名);
5、Path=<path-value>[可选]:指定一个URL路径,这个路径必须出现在要请求的资源的路径中才可以发送cookie首部;
6、Secure[可选]:只有在请求使用SSL和HTTPS协议的时候才会发送cookie到服务器;
7、HttpOnly[可选]:设置了HttpOnly属性的cookie不能使用JavaScript经由 document.cookie属性、XMLHttpRequest和Request APIs进行访问;
8、SameSite=<None|Strict|Lax>[可选]:设置了第三方cookie是否可以在跨站访问时被携带,Chrome 80+默认是Lax;
// 会话 cookie
Set-Cookie: sessionid=38afes7a8; HttpOnly; Path=/
// 持久 cookie
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2