standardBrowserEnv 标准浏览器中对 cookie 的读写删操作【玩转源码】

举报
叶一一 发表于 2023/07/26 12:32:36 2023/07/26
【摘要】 前言第一遍看 axios 源码,更多的是带着日常开发的习惯,时不时产生出点联想。第二遍再看 axios 源码,目标明确,就是奔着函数来的。当有了明确清晰的目标,阅读速度上来了,思绪也转的飞快。而本篇,主要是对standardBrowserEnv 标准浏览器中对 cookie 的读写删操作的思考。standardBrowserEnv 标准浏览器中对 cookie 的读写删操作一般基础的工具函数...

前言

第一遍看 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畅想」系列作者,华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。