cookie、session、webStorage详解

  cookie session localStorage sessionStorage
存放地点 客户端的内存或硬盘中 服务器的内存或硬盘中 客户端的硬盘 客户端的内存中
安全性 不安全 安全 安全 安全
存储容量 较小 无限制 无限制 无限制
数据种类 键值对 键值对 对象 对象
路径区分 有区别 无差异
有效期 由maxAge决定 由maxInactiveInterval决定 始终有效 关闭窗口就被销毁
作用域 不可跨域 不可跨域 在所有同源窗口中都是共享 看下文详解

 

Cookie:

  1. 所处请求中的位置:发送 http 请求时,存放于请求头为了保持状态,每次发送 http 请求都会携带这个 Cookie。
  2. 数据存储容量:在 http 协议中并没有对 Cookie 的数据容量做出规定,往往是由浏览器来决定的。因为每次请求都要携带着 Cookie,为了避免过多地占用带宽,所以各个浏览器一般都将 Cookie 的大小限制在一个很小的范围,各个浏览器所限制的具体大小也会有差异。
  3. 有效时间&存储位置:Cookie 的有效时间(单位:s)以及存储位置取决于 maxAge,如果maxAge为负数本次会话结束就清除 Cookie,那么 Cookie 保存在内存中就可以;如果 maxAge 是一个正数,这时即使关闭某个页面,也不会清除 Cookie,Cookie 会在过了在 maxAge 中所设定的时间才失效,那么 Cookie 就会被存储于硬盘中;为 时表示立即失效
  4. 删除&更新Cookie:response 对象关于 Cookie 并没有对应的删除、修改的方法,删除直接将 maxAge 修改为 0;想修改就需要创建一个新的同名 Cookie 来覆盖旧的 Cookie(注意:修改、删除 Cookie 时,新建的 Cookie 除 value、maxAge 之外的所有属性,例如 name、path、domain 等,都要与原 Cookie 完全一样。否则,浏览器将视为两个不同的 Cookie,不予覆盖,导致修改、删除失败。)
  5. 不可跨域:由于域名不同,Google 不能访问 Baidu 的 Cookie。
    1. 同一个一级域名下的两个不同二级域名的网站,生成的 Cookie 不同,也不会共享 Cookie,因为二者的域名并不严格相同。有特例,如 Google 对此有特殊处理,因此对于像 images.google.com 和 www.google.com 这样的两个网站,在一个网站登录后,在另一个网站中登录信息仍然有效。
    2. 如果想要让同一个一级域名下的所有二级域名都可以使用同一个 Cookie,先通过 cookie.setDomain() 来配置允许访问的域名,然后在本地访问 hosts 文件配置多个临时域名,使用 setCookie.jsp 来设置跨域名 Cookie 验证 domain 属性即可。
      1. 其中的 domain 属性值要以“.”开头,
      2. domain属性决定允许访问Cookie的域名。domain表示的是cookie所在的域,默认为请求的地址,如网址为www.test.com/test/test.aspx,那么domain默认为www.test.com。而跨域访问,如域A为t1.test.com,域B为t2.test.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.test.com;如果要在域A生产一个令域A不能访问而域B能访问的cookie就要将该cookie的domain设置为t2.test.com。
    3. name 相同但 domain 不同的两个 Cookie 也是两个不同的 Cookie。
  6. path 属性: 表示 Cookie 所在的目录,默认为 /,就是根目录。【在同一个服务器上有目录如下:/test/,/test/cd/,/test/dd/,现设一个 cookie1 的 path 为 /test/,cookie2 的 path 为 /test/cd/,那么 test 下的所有页面都可以访问到 cookie1,例如 /test/、/test/cd/、/test/dd/ 等等,也就是说 test 及 test 下的所有子页面都可以访问 cookie1。而 /test/ 和 /test/dd/ 的子页面不能访问 cookie2。这是因为他们并不属于 /test/cd/路径下的页面或者子页面。总结:Cookie 能让其 path 路径及子路径下的页面访问。
    1. 页面只能获取它所属的 path 下的 Cookie。例如 /session/test/a.jsp 不能获取到路径为 /session/abc/ 的 Cookie 。( path 属性决定允许访问 Cookie 的路径
    2. 可以使用 cookie.setCookie() 来设置 Cookie 的路径,设置为 “/” 时表示允许所有路径获取对应 Cookie。path 属性需要使用符号 “/” 结尾
    3. 浏览器会将 domain 和 path 都相同的 Cookie(还有可能会是名字等不同) 保存在一个文件里,Cookie 间用 * 隔开。
  7. 安全性:
    1. 通过 http 协议传输的 Cookie 没有经过任何加密,有被截获的风险,可以对其设置 secure 属性值为 true ,这样就只允许在 https 和 SSL 等安全协议中传输 Cookie。即使是这样,传输的 Cookie 也仍是明文,若想再次提高安全性,可以对 Cookie 进行加密、解密。
    2. JS 可以任意读写该域下的 Cookie,但无论如何都不能修改跨域对应的 Cookie,设置 HttpOnly 可以让 JS 操作只能读取 Cookie,避免 JS 可以任意修改该域下 Cookie 的问题。
  8. 字符类型:支持 ASCII(英文)、Unicode(中文)、Base64(图片)字符,使用 Unicode 字符时,需要进行对应的 Unicode 编码,不然会出现乱码,一般的编码方式是 UTF-8,不推荐使用 GBK,因为 JS 和部分浏览器不支持。
  9. 实质:
    1. 本质上 Cookie 可以被看做是 http 协议的一个扩展,有两个 http 头部就是与 Cookie 相关,一个是在响应报文中出现在头部的 "Set-Cookie",它由服务器生成,并带着一个 Cookie,用于告诉浏览器,需要在本地创建一个 Cookie,来保存我发送给你的 Cookie;另一个是 "Cookie",由浏览器生成,在请求头中出现,在本次回话中会带着自己的 Cookie,来告诉服务器自己的身份。
    2. 在 Java 中,cookie 是 Cookie 类的实例,在这个实例身上有两个方法,addCookie() 和 getCookie(),用于添加和获取客户端提交的所有 Cookie(数组的形式存在)
  10. 稳定性:Cookie 可能会被禁用,被禁用时,数据可以存储在 URL 或者是请求体中。这两种存储方式相对于 Cookie 存储会更稳定一些,因为它们不会被禁用。
  11. 查看方法:查看一个网站颁发的所有 Cookie 的方法:JavaScript:alert(document.cookie)。
  12. 存储规则:一个 Cookie 只能存储一个键值对,但是如果想在这个 Cookie 中存储多个值,可以让键值对的 value 为一个对象,在这个对象中保存多个值。

 

Session:

  1. 数据存储位置:为了提升访问速度,Session 一般保存在服务器的内存中(当然也可以保存在服务器磁盘中),因此,Session 中保存的数据也应该是短而精的。
    1. 在服务端会生成一个 session id 作为此次会话 Session 的身份码,发送至客户端之后,客户端通常将其保存在一个 Cookie 中(也叫客户端 Session ,也可以保存在 URL 中),用户每次访问服务器时带着该 Cookie,来告诉浏览器自己的身份。
      1. 保存 session id 的 Cookie 由服务端生成,保存于客户端,它的 maxAge 属性一般为–1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。
      2. 由一个窗口产生的子窗口,他们会共享父窗口的 Session。
  2. session id 生成位置:服务器会对 Session 生成一个身份码 session id,在响应中传递给客户端,供客户端保存。在从服务器传递给客户端的过程中,还是 session id ,到了客户端才被接收到 Cookie 中或别的位置。
  3. 服务器维护:Session 生成后,只要用户继续访问,服务器就会更新 Session 的最后访问时间,并维护该 Session。用户每访问服务器一次,无论是否读写 Session,服务器都认为该用户的 Session “活跃( active )”了一次。
  4. 不可跨域:不可跨域,但是可以有相应的共享方案:Session跨域共享问题解决
  5. 有效时间:
    1. Session 有一个像 Cookie 的过期时间一样的参数,叫做超时时间(maxInactiveInterval),Session 是否失效取决于用户在“超时时间”内是否活跃过,如果在“超时时间”内没有活跃就自动失效。
    2. 如果服务器设置的 session id 被保存到硬盘上,或者使用某种手段改写浏览器发出的 http 请求头,把原来的 session id 发送给服务器,再次打开浏览器仍然能够找到原来的 Session。
    3. 一定要注意,关闭浏览器窗口消失的只是 session id,Session 并没有消失,Session 想要消失需要在服务器手动删除,或者重启服务器来删除内存中的 Session,再或者就是在超时时间内没有活跃。
  6. 存储的数据特征:Session 中的数据也是键值对,只不过这个键值对很特殊,value 不仅仅可以是一般的数据类型,还可以是引用类型。
  7. 创建规则:只有访问 JSP、Servlet 等程序时才会创建 Session,只访问 HTML、IMAGE 等静态资源并不会创建 Session。如果尚未生成 Session,也可以使用 request.getSession(true) 强制生成 Session。
  8. 保存 sssion id 的方式:
    1. 一般保存 session id 的方式都是 Cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
    2. URL 地址重写:
      1. 概念:当浏览器禁止 Cookie 后,可以将 session id 放在 URL 的末尾,来保存 session id 以及供浏览器识别身份,这种技术就叫 URL 地址重写
      2. 有一个方法可以自动地判断是否支持 Cookie,当不支持 Cookie 时,自动地将 session id 放在原来 Cookie 的位置。服务器可以解析该 URL,获取到对应的 session id。
      3. 即使 URL 中带有 session id 也不一定是不支持 Cookie,因为在第一次请求时无 Cookie 可带,就会带上 session id,当接受到服务器的响应之后,本地也就可以存储 Cookie 了,下一次就还会带上 Cookie而不是 session id。
      4. URL 重写的方法有两个:(这两种方式对于客户端来说没有任何区别,但是对于服务端,第一种方式更容易让服务端将 session id 和普通参数区分开,为了始终保持状态,就需要让客户端的所有请求路径后面始终都带着这个 session id ):
        1. 一种是作为 URL 路径的附加信息:http://www.baidu.com/xxx; jsessionid= abc
        2. 另一种是作为查询字符串附加在URL后面,表现形式为http://www.baidu.com/xxx? jsessionid= def
    3. 另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。

 

localStorage:

  1. 安全性:域内安全。
  2. 有效时间:永久有效,除非手动删除。
  3. 域间关系:来自同一域名的所有页面都可访问localStorage数据,但客户端、浏览器之间的数据相互独立。
  4. 存储数据的类型:JSON字符串,当类型不为字符串类型时,会被自动转化为字符串。

 

sessionStorage:

  1. 安全性:域内安全。
  2. 有效时间:不论刷新或恢复页面都不会消失,会话一旦结束就会失效。
  3. 域间关系:
    1. 当在 a 页面有 sessionStorage 时,这时新增一个标签并输入与 a 页面相同的 URL。新的标签里面打开的页面是没有前一个标签页面里面的 sessionStorage 的。也就是讲,新标签是新的会话,哪怕是相同的 URL,不同 tab 之间就算相同 url,sessionStorage 也是不会共享的。sessionStorage 只存在于当前会话中
    2. _blank:  在 a 页面点击链接或者使用 window.open 打开与 a 页面相同 URL 的标签页面时,新标签页面 sessionStorage 继承自之前页面的 sessionStorage,但是后续两个页面的 sessionStorage 是单独控制的。两个页面之间并无关联。也就是说:使用window.open或者点击链接跳转的页面,新页面的sessionStorage会拷贝老页面的。但两者之间并无关联,还是两个会话。
  4. 存储数据的类型:JSON字符串,当类型不为字符串类型时,会被自动转化为字符串。

 

Web Storage带来的好处:
1、减少网络流量:一旦数据保存在本地之后,就可以避免再向服务器请求数据,因此减少不必要的数据请求,减少数据在浏览器和服务器间不必要的来回传递。
2、快速显示数据:性能好,从本地读数据比通过网络从服务器上获得数据快得多,本地数据可以及时获得,再加上网页本身也可以有缓存,因此整个页面和数据都在本地的话,可以立即显示
3、临时存储:很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用sessionStorage非常方便

 


参考博客:

  • cnblogs_session的存储方式和配置
  • cnblogs_sessionID和cookie
  • jianshu_session对象的理解
  • CSDN_sessionStorage详解
  • CSDN_localStorage存储数据的格式
  • CSDN_Web Storage详解
  • CSDN_Cookie

你可能感兴趣的:(计算机网络,前端面试题,session,cookie)