cookie的英文意思是饼干。在计算机术语中指服务端存放在客户端的一段数据。这段数据在客户端每次进行http请求时会自动加在http请求报文中的header上;服务端在响应时,能够对cookie进行设置,并将cookie加入到http响应报文header中。MDN中对cookie的解释为:cookie 是一个请求首部,其中含有先前由服务器经过 Set-Cookie 首部投放并存储到客户端的 HTTP cookies。
cookie通常存放在对应的域名下,各个浏览器对中一个域名下存放的cookie的个数与大小规定不同。下表是不一样浏览器对cookie存放的规定:前端
浏览器 | chrome | Safari | Firefox | ie |
---|---|---|---|---|
个数 | 53 | 无限制 | 50 | 50 |
大小 | 4097字节 | 4097字节 | 4097字节 | 4095字节 |
超额处理 | 剔除最老的cookie | 剔除最老的cookie | 随机消除除最新的其余cookie | 剔除最老的cookie |
全部浏览器都支持cookie功能,咱们能够直接在浏览器中移除cookie与禁用cookie存储。chrome中的设置为:设置-高级-隐私设置和安全性-内容设置-cookie。
若是咱们在建立cookie时没有设置过时时间,即没有设置expires或者max-age值,则该cookie只存在与会话中,此时,cookie存储在浏览器的内存中,关闭浏览器时cookie自动消失。若是设置了过时时间,则cookie存储在用户的硬盘上。
在windows OS下chrome存放cookie的路径是C:Documents and SettingsAdministratorLocal SettingsApplication DataGoogleChromeUser Data,firefox的存放路径是:C:Documents and SettingsAdministratorLocal SettingsApplication DataMozillaFirefoxProfilesznyzv8y6.defaultOfflineCache
在mac下chrome的存储路径为:~/library/application support/google/chrome;
Safari的存储路径为:~/library/cookies;node
咱们知道http协议是一种无状态的协议,在web应用程序中,经过http协议进行数据交互,交互完毕后,客户端与服务端的链接就断开。再次交互须要创建新的链接。这种链接没法记录用户的状态,cookie能够弥补HTTP协议无状态的不足。服务器给客户端们颁发一个通行证,不管谁访问都必须携带本身通行证,这样服务器就能从通行证上确认客户身份了。这就是Cookie的工做原理。jquery
上图展现了cookie的工做原理:
(1)第一次用户登陆的时候,输入用户名和密码信息,服务端接收后进行用户认证。
(2)服务端经过验证后,生成一个token以cookie的形式放在http的response header中一块儿返回给客户端。
(3)浏览器根据是否设置cookie的过时时间判断该cookie是会话cookie仍是永久cookie,并将cookie存储在不一样的位置。
(4)下次进行http请求时,请求头中会自动携带存储的cookie。
(5)服务端根据请求头中的cookie里面的token确认该用户的身份信息。ios
在解释这个问题以前先了解一下什么是跨域。两个域之间是否是存在跨域问题,主要是根据协议、域名、端口号这三个点进行判断,只要有一个不同就是跨域。例如:
(1)协议不一样:http://www.baidu.com 与https://www.baidu.com
(2)域名不一样:http://www.baidu.com 与http://www.google.com
(3)端口号不一样: http://www.baidu.com:8080 与http://www.baidu.com:8000
浏览器默认状况下没法主动跨域向后端发送cookie,须要在前端请求时加入配置项{withCredentials:true}。
jquery: $.ajax({url:'myurl',method:'GET', xhrFields:{withCredentials:true},success:function(){}})
;
angular: $http.get(url, {withCredentials: true})
axios: axios.defaults.withCredentials = true
web
前端配置好后还须要在后端进行相关配置:
在response header里面添加配置项ajax
"Access-Control-Allow-Credentials“, “true” "Access-Control-Allow-Origin", ”yourdomain“
也有一些中间件帮咱们解决跨域问题。例如express中的express-cors,或者koa中的koa-corschrome
设置:express
document.cookie = 'company=eoitek;max-age=10000;domain=eoitek.com;path=/;secure'
其中max-age是cookie的过时时间,是一个相对时间,值的单位是秒,是相对于cookie建立后多少秒才过时。与max-age类似的配置属性是expires,值为日期对象的toUTCString()格式,即Thu, 21 Sep 2018 06:10:38 GMT,是指cookie过时的绝对时间。若是max-age和expires都存在,则max-age的优先级更高。domain是咱们设置cookie存放的域,若是没有设置则为当前主机的域。path是指cookie存储的目录,默认为当前文件的存储目录。secure,加入此配置项,则指定该cookie只能经过https协议进行传输。
读取:axios
document.cookie
读取全部该域能获取到的cookie;格式为‘<key1>=<value1>;<key2>=<value2>;’windows
设置(以node为例):
var http = require('http'); http.createServer( function(req, res) { res.setHeader('status', '200 OK'); res.setHeader('Set-Cookie', 'name=binbinfang;path=/; max-age=1000;domain=eoitek.com'); res.setHeader('Access-Control-Allow-Origin', 'eoitek.com'); res.setHeader('Access-Control-Allow-Credentials', 'true'); res.write('Hello World'); res.end(); }).listen(8888); console.log('running localhost:8888');
后端cookie比前端cookie多两个配置项:
httpOnly:设置了 HttpOnly 属性的 cookie 不能使用 JavaScript 经由 Document.cookie 属性、XMLHttpRequest 和 Request APIs 进行访问,以防范跨站脚本攻击(XSS);
SameSite=Strict
SameSite=Lax
容许服务器设定一则 cookie 不随着跨域请求一块儿发送,这样能够在必定程度上防范跨站请求伪造攻击(CSRF)。
(1)保存中文cookie
若是须要保存中文cookie,则须要对中文进行UTF-8编解码,即经过encodeUriComponent()和decodeUriComponent()方。
(2)保存图片和安全证书
cookie中也能够保存二进制图片和安全证书,须要对文件进行base64编码才能保存。不过建议最好不要将这类文件保存在cookie中。
(3)cookie的更新
只要将key;path;domain一致,则能够经过改变key对应的value来更新cookie的值。
(4)cookie的删除
cookie只能更新不能删除,若是想要删除一个cookie,则经过更新设置该cookie的max-age=0便可。
(5)cookie的安全性
设置cookie时添加secure。
cookie因为其设置和取值都是经过字符串的形式进行的。所以,在原生cookie的操做比较麻烦,可经过一些js库来方便咱们的操做,包括cookies.js和js-cookie
默认状况下,cookie是不能跨域访问的,如在www.google.com域没法操做和获取www.baidu.com里面的cookie,由于他们的一级域不一样。可是在二级域里面能够共享和修改cookie的。即www.baidu.com和baike.baidu.com之间是能够共享cookie的。据此,能够实现单点登陆。
单点登陆:多个不一样系统整合到统一加载个平台,用户在任何一个系统登陆后,能够访问这个统一加载上的全部系统。登陆以后,用户的权限和信息再也不受某个系统的限制,即便某个系统出现故障(包括统一加载平台),其余系统仍是能正常使用的。这就须要用户权限等信息保存到客户端,不受服务器的限制。
例如,咱们有两个站点,都须要用户身份认证,要实现单点登陆的话,能够将他们的一级域名设置为相同的,如主站点设置为eoitek.test,子站点设置为sharplook.eoitek.test。在建立cookie的时候,经过设置domain=.eoitek.test;path=/;便可实现两个域名之间的cookie共享,若是将认证信息的token放在cookie中则能够实现单点登陆了。
//eoitek.test站点 import cookies from 'cookiesjs'; export default { name: 'agent', mounted() { cookies({'fullname': null, 'company': null}); if (!cookies('fullname')) { cookies({fullname: 'binbin', company: 'eoitek'}, {expires: 100 * 24 * 3600, domain: '.eoitek.test', path: '/'}); } } }
能够看出在两个站点中都能访问到咱们设置的两个cookie,这样实现了跨域访问cookie和单点登陆。