者:ConardLi 来源:code秘密花园
转载地址:https://mp.weixin.qq.com/s/7aWSZtitdOuMrRaxMZoYVQ
ookie 为 Web 应用程序保存用户相关信息提供了一种有用的方法。例如,当用户访问咱们的站点时,可以利用 Cookie 保存用户首选项或其他信息,这样,当用户下次再访问咱们的站点时,应用程序就可以检索以前保存的信息。
Cookie 是一小段文本信息,伴随着用户请求和页面在 Web 服务器和浏览器之间传递。用户每次访问站点时,Web 应用程序都可以读取 Cookie 包含的信息。
Cookie的出现是为了解决保存用户信息的问题。例如
Cookie 能在所有网页中记住用户的信息。它以字符串的形式包含信息,并键值对的形式保存的,即key=value的格式。各个cookie之间一般是以“;”分隔。
username=Daisy Green
服务器以cookie的形式向访问者的浏览器发送一些数据。如果浏览器允许接受 cookie。则将其作为纯文本记录存储在访问者的硬盘上。
当访问者跳转到另一个页面时,浏览器会将相同的cookie发送到服务器进行检索。一旦检索到它,您的服务器就知道或记得以前存储了什么。
Cookie 在HTTP的头部Header信息中,HTTP Set-Cookie的Header格式如下:
Set-Cookie: name=value; [expires=date]; [path=path]; [domain=domainname]; [secure];
在HTTP代码中一个具体的例子:
<meta http-equiv="set-cookie" content=" cookieName=cookieValue; expires=01-Dec-2006 01:14:26 GMT; path=/" />
从上面的格式可以看出,Cookie由下面几部分组成。
Name/Value对
Name/Value由分号分隔,一个Cookie最多有20对,每个网页最多有一个Cookie,Value的长度不超过4K。对于Value值,最好用encodeURIComponent对其编码。
Domain
Domain域名也是Cookie的一部分,默认情况下,用户访问网页的域名会存放在Cookie中。如果设置了这个Cookie的域名值,那么意味着域名上的所有服务器,而不仅是你正在访问的服务器,都能访问这个Cookie,通常不要这样做。设置域名的格式如下:domain=http://xyz.com
path
设置对于特定的服务器来说哪个目录中的网页可访问Cookie,设置path的格式是:path=/movies
Expires
设置Cookie存活的时间,默认情况下,用户关闭浏览器则Cookie自动删除,如果没有设置Cookie失效的时间,那么用户关闭浏览器时Cookie也消失。如果设置该项,就能延长Cookie的生命期。设置时间在JS 中用Date对象的GMT形式,格式如下: expires=date.toGMTString()
Secure
取true或者false值。如果为true,那么必须通过https发送Cookie。
在JS中,可以使用Document对象的cookie属性操作cookie。JS 可以读取,创建,修改和删除当前网页的cookie,,来看看具体的骚操作。
创建 Cookie
JS可以使用document.cookie属性创建cookie,可以通过以下方式创建cookie:
document.cookie="username=Daisy Green";
还可以添加有效日期(UTC 时间)。默认情况下,在浏览器关闭时会删除 cookie:
document.cookie="username=Daisy Green; expires=Mon, 26 Aug 2019 12:00:00 UTC";
通过 path 参数,可以告诉浏览器 cookie 属于什么路径。默认情况下,cookie 属于当前页。
document.cookie="username=Daisy Green; expires=Mon, 26 Aug 2019 12:00:00 UTC"; path=/";
读取 Cookie
通过 JS,可以这样读取 cookie:
var x=document.cookie;
document.cookie 会在一条字符串中返回所有 cookie,比如:cookie1=value; cookie2
事例:
<html> <head> <script type="text/javascript"> <!-- function ReadCookie() { var allcookies=document.cookie; document.write ("All Cookies : " + allcookies ); // Get all the cookies pairs in an array cookiearray=allcookies.split(';'); // Now take key value pair out of this array for(var i=0; i<cookiearray.length; i++) { name=cookiearray[i].split('=')[0]; value=cookiearray[i].split('=')[1]; document.write ("Key is : " + name + " and Value is : " + value); } } //--> </script> </head> <body> <form name="myform" action=""> <p> click the Button to View Result:</p> <input type="button" value="Get Cookie" onclick="ReadCookie()"/> </form> </body> </html>
运行:
改变 cookie
通过使用 JS,咱们可以像创建 cookie 一样改变它:
document.cookie="username=Steve Jobs; expires=Sun, 31 Dec 2017 12:00:00 UTC; path=/";
这样旧 cookie 会被覆盖。
事例:
<html> <head> <script type="text/javascript"> <!-- function WriteCookie() { var now=new Date(); now.setMonth( now.getMonth() + 1 ); cookievalue=escape(document.myform.customer.value) + ";" document.cookie="name=" + cookievalue; document.cookie="expires=" + now.toUTCString() + ";" document.write ("Setting Cookies : " + "name=" + cookievalue ); } //--> </script> </head> <body> <form name="myform" action=""> Enter name: <input type="text" name="customer"/> <input type="button" value="Set Cookie" onclick="WriteCookie()"/> </form> </body> </html>
运行:
删除 cookie
删除 cookie 非常简单,不必指定 cookie 值:直接把 expires 参数设置为过去的日期即可:
document.cookie="username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
应该定义 cookie 路径以确保删除正确的 cookie。如果不指定路径,有些浏览器不会让咱们删除 cookie。
事例:
<html> <head> <script type="text/javascript"> <!-- function WriteCookie() { var now=new Date(); now.setMonth( now.getMonth() - 1 ); cookievalue=escape(document.myform.customer.value) + ";" document.cookie="name=" + cookievalue; document.cookie="expires=" + now.toUTCString() + ";" document.write("Setting Cookies : " + "name=" + cookievalue ); } //--> </script> </head> <body> <form name="myform" action=""> Enter name: <input type="text" name="customer"/> <input type="button" value="Set Cookie" onclick="WriteCookie()"/> </form> </body> </html>
参考:https://www.w3schools.com/js/js_cookies.asp
我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!
关注公众号,后台回复福利,即可看到福利,你懂的。
如果小伙伴最近有访问国外的一些标准网站的话,可能经常会弹出一个对话框,说是本网站为了更好的体验和跟踪,需要访问你的cookies,问你同意不同意,对于这种比较文明的做法,我一般是点同意的。
但是转头一想,为什么访问国内的网站从来没有弹出过这个提示呢?这是一个值得深思的问题,或许当你看完这篇文章之后,就有了答案。
那么cookies有什么作用呢?HTTP cookies就是服务器端发送给浏览器端的一小部分数据,浏览器接收到这个数据之后,可以存起来自己用,也可以在后续发送到server端进行一些数据的校验。
通过在cookies中存储一些有用的数据,可以将无状态的HTTP协议变成有状态的session连接,或者用来保存登录的权限,下次不用密码即可登陆,非常有用。
一般来说,cookies用在三个方面:
在很久很久以前,还没有现代浏览器的时候,客户端的唯一存储就是cookies,所以cookies也作为客户端存储来使用的,但是有了现代的浏览器之后,一般是建议把客户端存储的数据放到其他存储方式中。
为什么呢?
因为每次请求cookies中的数据会自动带上,并且发送到server端,所以如果cookies中存储了太多的数据,就会导致服务器性能的下降。
因为cookies是客户端的本地存储,所以如果服务器端想要设置客户端的cookies时,通过在响应头中设置Set-Cookie,浏览器接收到这个响应头之后,就会将对应的cookies内容存储到浏览器本地。
然后在后续的服务器请求中都会带上Cookie header。同时cookie还可以带上过期时间、发送限制等属性。
先来看下Set-Cookie的格式:
Set-Cookie: <cookie-name>=<cookie-value>
举个例子,下面是一个server端的响应:
HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: name=flydean
Set-Cookie: site=www.flydean.com
当浏览器接收到这个响应之后,就会在本地的cookies中设置对应的值,并且在后续的请求中将这些值以cookies的header形式带上:
GET /test.html HTTP/2.0
Host: www.flydean.com
Cookie: name=flydean; site=www.flydean.com
在netty中提供了一个Cookie的类,专门用来表示cookies,这个类中提供了cookies的基本属性,然后通过使用:
response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(cookie));
来对响应头进行设置。
HTTP的cookies有两种,一种是session cookies,这种cookies会在session结束之后自行删除。
还有一种cookies通过指定Expires或者 Max-Age 来设置过期时间:
Set-Cookie: id=abcdef; Expires=Thu, 31 May 2021 08:00:00 GMT;
其中Expires是HTTP1.0中定义的header,Max-Age是HTTP1.1中定义的header。
HTTP提供了两个属性来对cookies的权限进行控制,分别是Secure和HttpOnly。
如果cookies中带有Secure属性,那么cookies只会在使用HTTPS协议的时候发送给服务器。如果使用的是HTTP协议,则不会发送cookies信息。
并且,如果是在http的情况下,server端是不允许给cookie设置Secure属性的。
但是设置了Secure属性并不意味着cookies就是安全的,因为可以从其他的手段拿到浏览器端的cookies。
还有一个属性是HttpOnly,如果cookies设置了HttpOnly,那么cookies是不允许被JavaScript访问的,通过设置HttpOnly,我们可以提升客户端数据的安全性:
Set-Cookie: id=abcdef; Expires=Thu, 21 May 2021 08:00:00 GMT; Secure; HttpOnly
cookies还可以添加Domain和Path属性,用于标记cookies可以发送到的URL。
其中Domain表示域名,而Path表示路径。
如果Domain没有设置,则默认是设置cookies的host,这个host是不包含子domain的。如果手动指定了Domain,那么子domain是会包含在内的。
比如如果我们设置了Domain=flydean.com,那么子domain:doc.flydean.com也会共享这个cookies。
Path用来匹配URL的路径,只有匹配到的URL才可以发送cookies。
另外HTTP还提供了一个SameSite属性,表示如果是在CORS环境情况下,是否发送cookies到第三方网站,这样可以在一定程度上保护网站的信息。
SameSite有三个可能的值,分别是Strict, Lax, 和 None。如果在Strict情况下,那么cookie仅发送到与创建它的站点相同的站点。Lax跟Strict类似,不同之处在于当用户导航到cookie的原始站点时发送cookie,比如通过访问外部站点的链接。 None可以在原始网站和跨站资源访问中使用,但是必须要在安全的环境中进行(设置Secure属性)。如果没有设置SameSite,那么表现是和Lax一致的。
例如:
Set-Cookie: name=flydean; SameSite=Strict
我们知道cookies是和domain相关的,如果cookies的domain是和当前访问的页面相同的话,这个cookies就叫做 first-party cookies。如果和当前的访问页面不同,比如访问第三方的图片、脚本、css等,第三方的服务器有可能会发送他们自己的cookies,这种cookies叫做第三方cookies,第三方cookies主要被用来广告或者跟踪用户的行为信息。
对于有些浏览器来说,可能会禁用第三方的cookies,这有可能会导致访问网站的一些功能问题,大家可以主要观察一下。
使用cookies可以辅助我们做很多事情,但是也要注意cookies的安全性。
本文已收录于 http://www.flydean.com/05-http-cookie/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
*请认真填写需求信息,我们会在24小时内与您取得联系。