0. 从http协议的无状态性说起

  • http 是无状态的协议
  • 无连接:处理完一个请求就断开链接(http1.1以后可以实现长连接)
  • 无状态:上一次会话与下一次会话没有联系。
  • 可以通过 cookie 来维护状态信息。

1. cookie

存储大小:每条的存储空间为4k;

特点:

- cookie没有显示的删除函数,可以设置 expire/max-age 过期时间,自动触发浏览器的删除机制。
- 服务器通过设置响应头来设置客户端的cookie,Set-Cookie: cookie-名=cookie值。可以同时添加多个Set-Cookie,从而设置多个cookie的值。
- 不允许存储敏感信息(用户名,密码等),一定要存储,要设置 cookie为 httponly, 另外考虑使用 非对称加密
- 浏览器 中的cookie 数量达到上限后,会删除旧的创建新的,删哪个由浏览器的策略决定
- cookie 通常与 session 一起使用。
    - 登录时,server 端存储 用户信息相关的 session。
    - server 端,生成的 sessionid 会放在cookie中,对应域名下就有了这个cookie。
    - 以后会自动带这个 cookie,server 根据id 找到 session,获取用户信息。

基本操作

  • 客户端:
// 读取:
document.cookie
// 设置:
document.cookie = 'myNmae=liulanqi;path=/;domain=.baidu.com';
  • 服务端:

    • 使用 setCookie 来设置,在设置多个 cookie的时候,得多写几个 setCookie。

设置cookie:

    document.cookie="userId=828";
    document.cookie="userName=hulk"; 
    此时浏览器将会维护两个cookie,分别为userId和userName;相当于:
    document.addCookie("userId=828");
    document.addCookie("userName=hulk");
    如果要改变一个cookie的值,只需重新赋值,例如:
    document.cookie="userId=929";

获取cookie:

var strCookie=document.cookie;
console.log(strCookie); //userId=828; userName=hulk
- 只能一次获取所有的cookie的值,而不能指定cookie名称来获得指定的值。
- 如果在某个页面创建了一个cookie,那么该页面所在目录中的其他页面也可以访问该cookie。
- 为了控制cookie可以访问的目录,需要使用path参数设置cookie。document.cookie="userId=320; path=/shop";就表示当前cookie仅能在shop目录下使用。
  • 常用的cookie操作及其函数实现:

    • addCookie(name, value, expireHours):
        function addCookie(name,value,expireHours){
             var exdate = new Date();    
            exdate.setTime(exdate.getTime() + expireHours * 60 * 60 * 1000);    
              document.cookie = name + "=" + escape(value) + ((expireHours == null) ? "" : ";expires=" + exdate.toUTCString());
        }
        toUTCString() 方法可根据世界时 (UTC) 把 Date 对象转换为字符串,并返回结果。
    • getCookie(name):
        function getCookie(name){
            let arr, reg = new RegExp(`^| ${name} = [^;]*;|$`);
            if (arr = document.cookie.match(reg)) return arr[2];
            else return null;
        }
  • cookie的可选项:

    • expires/max-age: 设置过期时间。

      • expires是绝对时间,max-age是相对时间。
      • 如果没有设置过期时间,则表示是一个会话期cookie,在关闭浏览器后,会被移除。
      • 浏览器支持会话恢复,保留cookie。
      • 正数,表示 多少秒后失效
      • 负数,该 cookie 是临时 cookie,关闭浏览器就失效,浏览器页不会以任何形式保存该 cookie
      • 为 0,表示删除 cookie
    • domain和path:

      • path,设置必须匹配的路径或者子路由才会发送cookie。如果路径设为/forums/,那么这个 Cookie 只有在访问www.example.com/forums及其子路径时才有效。
      • path 的设置,必须以 ‘/’结尾
      • domain 的设置,第一个字符必须是 ‘.’, 比如“.baidu.com”
      • domain标识指定了哪些主机可以接受cookie。如果没有设置,则是当前主机(不包含子域名),否则为设置的域名(包含子域名)。
    • secure和httponly:

      • secure标志cookie只能通过https传输,可以防止xss攻击。
      • httponly表示cookie无法通过javascript调用,防止中间人劫持。把cookie设置为secure,只保证 cookie 与服务器之间的数据传输过程加密,而保存在本地的 cookie文件并不加密。如果想让本地cookie也加密,得自己加密数据。
    • samesite:可以设置 SameSite:SameSite=Strict SameSite=Lax。则 cookie 不跨域发送。ajax中设置xhr.withCredentials = true;

问题:

- 问题:“www.qq.com” 与 “sports.qq.com” 公用一个关联的域名”qq.com”,我们如果想让”sports.qq.com” 下的cookie被 “www.qq.com” 访问:
- 解答:我们就需要用到cookie 的domain属性,并且需要把path属性设置为 “/“。例:document.cookie = “username=Darren;path=/;domain=qq.com“
- 问题:同域名的资源请求时,会默认带上本地的cookie,如何优化?
- 解答:将静态资源分组,分别放在不同的子域下(子域名请求时,是不会带上父级域名的cookie的)

cookie 的跨域问题

  • 域名、端口相同就不算跨域,协议可以不同。

使用cookie需要考虑的问题

  • 因为存储在客户端,容易被客户端篡改,使用前需要验证合法性
  • 不要存储敏感数据,比如用户密码,账户余额
  • 使用 httpOnly 在一定程度上提高安全性
  • 尽量减少 cookie 的体积,能存储的数据量不能超过 4kb
  • 设置正确的 domain 和 path,减少数据传输
  • cookie 无法跨域
  • 一个浏览器针对一个网站最多存 20 个Cookie,浏览器一般只允许存放 300 个Cookie
  • 移动端对 cookie 的支持不是很好,而 session 需要基于 cookie 实现,所以移动端常用的是 token

默_hjh
32 声望1 粉丝

下一篇 »
session