作为保存用户信息的几种方式,经常让人傻傻分不清楚,索性逐个记录下来,分析比较一番。
一、cookie
cookie 是什么?
cookie 是服务器下发给浏览器的一段字符串,浏览器必须保存这个字符串,除非用户删除,保存后当用户再发起相同二级域名下的任何请求时,浏览器都必须附上 cookie。
形象地解释一下,cookie 就好比是公园的门票,当你入园的时候就需要携带这张门票,而门票中就保存了你的身份信息,接下来你就可以凭借着这个门票去公园里的任何地方。
cookie 中也保存着你的个人数据,服务器发放给你后,当你再去相同域名下的其他网页时,都会自动带着这个信息,而服务器在响应其他页面的时候也就可以通过这个 cookie 获取你的身份,然后返回给你独有的内容。
很常见的一个场景就是当用户成功登录后显示用户的用户名,如果没有登录则显示请登录,实现的方式就是当用户输入基本信息然后点击提交后,后端在响应的时候检验用户输入的信息是否匹配,如果成功匹配那么返回请求成功状态,同时通过在 "Set-Cookie" 中设置用户的信息发送给浏览器,而浏览器就会自动在本地保存这个 cookie 的内容,而后如果浏览器再发起请求首页的内容,发起的时候又会自动附带上 cookie 的信息给服务器,服务器处理首页请求的时候就可以通过 headers 中的cookie 字段获取用户的身份,获取后可以通过数据库的查询得到用户的更多内容并再将之返回给浏览器,最后呈现在页面中。
这样说来,cookie 是在服务器中设置的,在浏览器中保存,而后跟着请求再把数据返回给服务器,那么浏览器可以操作 cookie 吗?答案是可以,我们可以通过 document.cookie 设置 cookie 的内容,也可以直接通过开发者工具进行修改,但是我们一般不能把操作 cookie 放在前端,因为后端的程序会根据 cookie 的信息做出不同的响应,而如果用户可以随意修改 cookie 的话,那么就会很容易扰乱后端的程序。另外,后端可以在设置 cookie 的时候加上 HttpOnly 或者其他方式,阻止前端操作 cookie。
二、session
session 是什么?
session 本身是一个抽象概念,代表服务器和客户端的一段会话,一种会话状态,在实现层面来说,它是存储在服务器中的一些数据,这些数据可以保存在文件、数据库或者其他,一般情况下通过 sessionId 和 cookie 相互配合,来达到跟踪用户的状态的目的,具体怎么实现呢?
上面谈到使用 cookie 来存储用户的个人信息或者是登录信息,你能很快发现如果我们就这样直接明文存储在 cookie 里,那么用户信息就可以很容易被泄露,坏人完全可以通过本地查看你的信息,然后模仿你登录。那么如何解决这个问题呢?
解决的方式很明显,直接加密不就好了吗,存储的时候加密,读取的时候解密,反正都在后端操作,前端又不需要操作 cookie ,这样做是可取的,但是也可以通过 session 的方式来避免这个问题。
使用 session 的解决思路就是在每次用户登陆成功后,在后端响应设置 cookie 的时候,我们并不直接在 cookie 中设置用户的信息,而是生成一个随机数(称为 sessionId),通过键值对的方式将该随机数和要保存的用户信息对应起来,存储在服务器内(例如存储在服务器中的一个文件里),然后将该随机数设置在 cookie 里,此后用户再发起其他页面的请求时,在后端就通过得到该随机数去查询用户的信息,当用户退出登录后就再删除对应的内容,如果用户再次登录就再次创建,因此用户信息就只是在一个会话阶段被保存,而 cookie 中的内容也只是一个随机数而已。
三、localStorage VS sessionStorage
和 cookie、session 一样,这两者也是用来保存数据的,和 session 不同,它们都保存在浏览器中,与 cookie 不同,它们并不会放在请求里发送到服务器上,它们都是在本地存储且在本地使用,同时都特定于页面的协议。
localStorage 中的键值对总是以字符串的形式存储,里面的数据可以长期保留,除非用户手动删除,可以存储的数据量在 5m~10m 之间,具体的数据量大小根据浏览器而定,不同的浏览器有所不同。
sessionStorage 和 localStorage 的用法很相似,不同之处在于存储在 sessionStorage 中的数据会在页面会话结束时清除,并不会长期保留。它具有如下特点:
1.页面会话在浏览器打开期间一直保存,并且重新加载或恢复页面仍会保持原来的页面会话。
2.打开多个相同的 url 的 tabs 页面,会创建各自的 sessionStorage。
3.关闭浏览器窗口 / tab ,会清除对应的 sessionStorage。
4.在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文。
sessionStorage 的使用场景:当用户输入内容时,如果浏览器因偶然因素被刷新了,利用 sessionStorage 自动恢复文本输入框里面的内容,用户写入的内容就可以不丢失。
四、总结
最后总结一下:
Cookie V.S. localStorage
-
Cookie 会被发送到服务器,而 localStorage 不会。
-
Cookie 一般最大 4k,localStorage 可以用 5Mb 甚至 10Mb(各浏览器不同)。
localStorage V.S. sessionStorage
localStorage 一般不会自动过期(除非用户手动清除),而 sessionStorage 在回话结束时过期(如关闭浏览器)。
Cookie V.S. Session
-
Cookie 存在浏览器的文件里,Session 存在服务器的文件里。
-
Session 是基于 Cookie 实现的,具体做法就是把 SessionID 存在 Cookie 里。
欢迎大家留言讨论。