内容参考来自:https://segmentfault.com/a/1190000016717878,https://blog.csdn.net/skh2015java/article/details/53560044 ,
https://juejin.im/entry/582d5664a0bb9f0067a6f863
商业转载需本作者同意。
Cookie:小饼干是什么呢,是服务器保存在浏览器的一小段文本信息,可以用来存储状态信息。
- 当用户访问web页面时,他的记录可以保存在cookie中。
- 在用户下一次访问同一页面时,可以在cookie中读取用户的访问记录。
Cookie特点
- 每个cookie的大小不能超过4KB。
- 通过HTTP协议的方式来存储数据。
- cookie会影响同一域名下的根目录及其子目录。举例来说,如果当前URI是keithchou.github.io,如果设置path为’/'或者不设置(默认值为/),这个cookie对该域名的根路径和它的所有子路径都有效。如果path设置为/music,那么这个cookie只有在访问keithchou.github/music及其子路径才有效。
- 同源政策。浏览器的同源政策规定,两个网址只要域名和端口相同,就可以共享cookie。注意,这里不要求协议相同。也就是说,'keithchou.com’设置的cookie,可以被’https://keithchou.…。
实现
服务器通过设置:
Set-Cookie:<cookie名>=<cookie值>
可以添加多个set-cookie,从而设置cookie的值。
Set-Cookie有几个选项:
Expires/Max-age:设置过期时间;
Expires为某个日期的GMT格式,Max-age为需要经过的秒数,优先级比expires高。没有设置时间,默认会话cookie,关闭浏览器就移除。
Domain和Path:
Path设置必须是匹配的路径和子路径才会发送cookie,domain表示指定了哪些主机可以接受cookie。若没有设置,则为当前的主机。
Secure和HTTPOnly:
Secure标志cookie只能通过https传输,可以防止xss攻击;
HttpOnly表示cookie无法通过JavaScript调用,防止中间人劫持;
SameSite:
设置SameSite=strict SameSite=Lax,则cookie不跨域发送。
第三方Cookie:对于 post,ajax 可以标示 withCredentials 从而跨域携带 cookie,fetch 可以设置 credentials:‘include’。
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://a.test/hhh12');
xhr.withCredentials = true;
xhr.send();
fetch('http://a.test/hhhaaaaa12', { credentials: 'include' });
浏览器可以关闭第三方 cookie。(如果应用了 p3p 协议则无法关闭)。
通过第三方 cookie 广告商可以标示用户,从而进行跟踪。
JavaScript和cookie
使用document.cookie可以获取所有非http-only标志的cookie。
document.cookie = newCookie 可以是一个新cookie。
如果要一次存储多个名称/值对,可以使用分号加空格隔开。如:
document.cookie=“id=77; name=bill”;
在cookie的名或值中不能使用分号(;)、逗号(,)、等号(=)以及空格。如果想存入这些值,我们可以使用escape()函数进行编码,它能将一些特殊符号使用十六进制表示,例如空格将会编码为“%20”,从而可以存储于cookie值中。
例如:
document.cookie="str="+escape("Hello World");
相当于:
document.cookie="str=Hello%20World";
当使用escape()编码后,在取出值以后需要使用unescape()进行解码才能得到原来的cookie值。
改变cookie 的值只能重新赋值,
cookie的值可以由document.cookie直接获得:var strCookie=document.cookie;
如果是一次存入多个名称/值对,可以将获取到的字符串进行遍历。
在实现一个小型cookie操作库,之前我们来了解下URI统一资源标识符,组成一般形式:
以下内容来自:https://juejin.im/post/5835836361ff4b0061f38a5d
Scheme : First / Second ; Third ? Fourth
其中斜体的名字代表组件;“:”, “/”, “;”,“?”是当作分隔符的保留字符。
encodeURI 和 decodeURI 函数操作的是完整的 URI。对整个URL进行编码,而URL的特定标识符不会被转码。
encodeURIComponent 和 decodeURIComponent 函数操作的是组成 URI 的个别组件;这俩函数假定任何保留字符都代表普通文本。
对URL中的参数进行编码,因为参数也是一个URL,如果不编码会影响整个URL的跳转。
例如:
document.write(encodeURIComponent("https://mp.csdn.net/mdeditor/88958821#"));
输出:
https%3A%2F%2Fmp.csdn.net%2Fmdeditor%2F88958821%23
以下是实现操作一个cookie的代码:
var miniCookie = {
//写入
set:function(name,value,expires,path,domain,secure){
var cookieText = encodeURIComponent(name) + "="+
encodeURIComponent(value);
if (expires instanceof Data){
cookieText += ";expires="+expires.toGMTString();
}
if(path){
cookieText += ";path=" +path;
}
if(domain){
cookieText += ";domain="+domain;
}
if(secure){
cookieText += ";secure";
}
document.cookie = cookieText;
},
//读取,cookie="name=crr;sex=girl;age=24"
get:function (name) {
var cookieName = encodeURIComponent(name) + "=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if (cookieStart > -1){
//stringObject.indexOf(searchvalue,fromindex)
var cookieEnd = document.cookie.indexOf(";",cookieStart);
if (cookieEnd == -1){//如果不存在,则只有一个cookie
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart+cookieName.length,cookieEnd));
}
return cookieValue;
},
//删除
unset: function (name,path,domain,secure) {
this.set(name,"",new Data(0),path,domain,secure);
}
};