前言

第一遍看 axios 源码,更多的是带着日常开发的习惯,时不时产生出点联想。

第二遍再看 axios 源码,目标明确,就是奔着函数来的。

当有了明确清晰的目标,阅读速度上来了,思绪也转的飞快

而本篇,主要是对standardBrowserEnv 标准浏览器中对 cookie 的读写删操作的思考。

standardBrowserEnv 标准浏览器中对 cookie 的读写删操作

一般基础的工具函数都会放到 utils.js 文件中。前一篇源码阅读中,介绍了关于类型判断的两种方法。

axios 中有许多模块,不同的模块下包含不同的功能。除了 utils.js 文件,这些模块下的文件也包含函数。我称之为功能函数。

功能函数,按照实际功能需要封装的函数,也许并不是常见功能需要的,但是了解之后,没准能帮助今后用到的时候,快速完成开发。

cookie 的格式

通过 document.cookie 获取 cookie 的值,是一串有特定格式的字符串。它的格式是

cookie1=value; cookie2=value; cookie3=value;

了解了 cookie 的格式,对于它的操作,也自然而然的可以接着看代码了。

cookie 的读写删

在标准浏览器中,对 cookie 的处理被封装在了一个立即执行函数里。

(function standardBrowserEnv() {
  return {
		/**
     * cookie 写入(创建)单个写入
     * @param {string} name cookie 名
     * @param {string} value cookie 值
     * @param {*} expires 过期时间
     * @param {*} path cookie所在的目录
     * @param {*} domain cookie所在的域
     * @param {*} secure 是否可以通过HTTP协议的URL设置布尔值 值为 true 时,表示创建的 cookie 只能用 HTTPS 协议发送
     */ 
    write: function write(name, value, expires, path, domain, secure) {
    	// 先将所有的数据存入数组
      const cookie = [];
      cookie.push(name + '=' + encodeURIComponent(value));

			// 如果过期时间有值且是数值型,则存入其转为根据格林威治时间 (GMT) 转成的字符串
      if (utils.isNumber(expires)) {
        cookie.push('expires=' + new Date(expires).toGMTString());
      }

    	// 当目录存在且为字符串,则存入cookie
      if (utils.isString(path)) {
        cookie.push('path=' + path);
      }

			// 当域存在且为字符串,则存入cookie
      if (utils.isString(domain)) {
        cookie.push('domain=' + domain);
      }

			// 是否可以通过HTTP协议的URL设置布尔值为 true 时,则存入cookie
      if (secure === true) {
        cookie.push('secure');
      }

    	// 将数组转为字符串,并通过 document.cookie 属性来创建 cookie
      document.cookie = cookie.join('; ');
    },

		/**
     * cookie 读取 单个读取
     * @param {string} name cookie 名
     */
    read: function read(name) {
    	// 正则匹配得到数组
      const match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
    	// match 匹配的返回值中第四个元素为需要的值
      return match ? decodeURIComponent(match[3]) : null;
    },

  	/**
     * cookie 删除 单个删除
     * @param {string} name cookie 名
     */
    remove: function remove(name) {
			// 将过期时间设置为过去的时间,即可删除 cookie, 这里设置成了前一天(86400000为1天的毫秒数)
      this.write(name, '', Date.now() - 86400000);
    },
  };
})();

使用

// 写入
cookies.write('foo', 'bar');
// 删除
cookies.remove('foo');
// 读取
cookies.read('username=John Doe') // => John Doe

功能汇总

日期转换 toGMTString 方法

toGMTString() 方法可根据格林尼治标准时间 (GMT) 把 Date 对象转换为字符串,并返回结果。

介绍这个方法,主要科普一个新旧交替的世界标准时间。

首先这个 GMT 和 UTC 的定义如下:

GMT(Greenwich Mean Time):格林尼治标准时间。格林尼治是英国伦敦南郊原皇家格林尼治天文台所在地,地球本初子午线的标界处,世界计算时间和经度的起点。格林尼治标准时间过去被当成世界标准的时间。

UTC(Coordinated Universal Time):协调世界时。又称世界统一时间、世界标准时间、国际协调时间。协调世界时是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。协调世界时是现在使用的世界标准时间。

所以在W3C下面有一行提示:

不赞成使用此方法。请使用 toUTCString() 取而代之!!

toUTCString 方法

根据协调世界时 (UTC) 把 Date 对象转换为字符串,并返回结果。

正则 match 方法

match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。

返回值

它的返回值是一个存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g。

  • 如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。
  • 如果找到匹配结果,它将返回一个数组,存放了与它找到的匹配文本有关的信息。数组的第1个元素存放的是匹配的文本,其余的元素存放与正则表达式的子表达式匹配的文本和input、index、groups三个元素。
  • 如果没找到匹配结果,返回 null。
  • 如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。
  • 如果找到匹配结果,它将返回一个数组,数组的第1个元素存放的是匹配的文本,其余元素存放匹配的一个或多个文本。
  • 如果没找到匹配结果,返回 null。

总结

先来总结一下文章:

  1. 对 cookie 的读写删操作还是挺简单的,主要是参数要考虑全面。日常开发中使用频率不是很高,但是如果需求涉及到可以帮助快速完成开发。
  2. 在 standardBrowserEnv 函数中,不难在里面发现 utils 的身影,所以基础工具函数的建设必不可少。
  3. 把 Date 对象转换为字符串推荐使用 toUTCString 方法。
  4. 无法删除的属性,可以设置成无效的值,比如这里的通过过期时间提前于当前时间。再比如前一篇介绍过将属性值设置为 undefined。

作者:非职业「传道授业解惑」的开发者叶一一简介:「趣学前端」、「CSS畅想」系列作者,华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。