前端缓存使用规范

一、Cookie使用规范

cookie的存储空间非常有限且会携带在请求头中会浪费不必要的流量,如果仅仅是为存储数据,可以采用其他替代方案,例如 webStorage,非必要不使用cookie。

1、使用方法

注意:过期时间时需转换成UTC格式

javascript 复制代码
//创建 &修改-设置过期时间为30分钟
document.cookie=`KN=Joy;domain=.docs.paic.com.cn';path=/#/post;expires=${new Date(new Date().getTime() + 1800000).toUTCString()}`
// 删除,需要删除的cookie只需要将过期时间设置为当前时间即可
document.cookie=`KN=Joy;domain=.docs.paic.com.cn';path=/#/post;expires=${new Date().toUTCString()}`
//查看
console.log(document.cookie)//cookie目前没有api可以直接拿到key值,只能拿到所有的cookie再做过滤
// 取值方法参考
function getCookie (cookieName) {
    var allcookies = document.cookie
    var cookiePos = allcookies.indexOf(cookieName + '=')
    if (cookiePos !== -1) {
       cookiePos += cookieName.length + 1
        var cookieEnd = allcookies.indexOf(';', cookiePos)
            if (cookieEnd === -1) {
                cookieEnd = allcookies.length
             }
             allcookies = allcookies.substring(cookiePos, cookieEnd) 
             if (allcookies && allcookies.indexOf('{') === 0) {
                 return JSON.parse(allcookies || '{}');
               } else {
                 return allcookies;
             }
         } else {
          return {}
       }
  },

2、使用场景

  • 数据透传 ,cookie可以跨域,在同一父域可以共享;
  • 服务端创建的数据 ,若只涉及后端使用注意使用httpOnly属性;
  • 全局数据,可做全局数据缓存在cookie中。

3、替代方案

cookie前后端都可以写入,在非必要不创建cookie的前提下,前后端都应该对cookie保持克制

  • 数据透传 ,url带参可以实现数据透传;
  • 服务端创建的数据 ,通过responents返回,再由前统一设置到请求参数体中;
  • 全局数据 ,使用webStorage替代存储,例如localStoragesessionStorage

4、使用规范

1. key由1~4位大写字母、数字、下划线组成 ,命名尽量精简; 例如 userInfo,可以命名为UI

javascript 复制代码
//good
document.cookie=`UI=Joy;domain=.docs.paic.com.cn';path=/#/post;expires=${new Date(new Date().getTime() + 1800000).toUTCString()}`
document.cookie=`BP_D=ndnakswwww;domain=.docs.paic.com.cn';path=/#/post;expires=${new Date(new Date().getTime() + 1800000).toUTCString()}`

//bad
document.cookie=`userInfo=Joy;domain=.docs.paic.com.cn';path=/#/post;expires=${new Date(new Date().getTime() + 1800000).toUTCString()}`
document.cookie=`bankparam-data=ndnakswwww;domain=.docs.paic.com.cn';path=/#/post;expires=${new Date(new Date().getTime() + 1800000).toUTCString()}`

2. value单个长度不超过200个英文字符,大小不超过400B

3. 禁止存入直接由JSON格式转成的字符串 , 直接由JSON转成字符串会增加{}""占用不必要的内存,改为kv格式存储,以&连接符区分,例k=1&k2=2

javascript 复制代码
//好例子
var userInfo={
	name:'joy',
	age:18
}
var data = JSON.stringify(userInfo)

var parseData=Object.keys(userInfo).reduce((cur,acc,index)=>{
	let icon=index?'&':''
	return  cur+ icon+acc+'='+userInfo[acc]
},'')//name=joy&age=18
document.cookie=`UI=${parseData};domain=.docs.paic.com.cn';path=/#/post;expires=${new Date(new Date().getTime() + 1800000).toUTCString()}`
//坏例子;将json直接转成字符串存入cookie中
document.cookie=`UI=${data};domain=.docs.paic.com.cn';path=/#/post;expires=${new Date(new Date().getTime() + 1800000).toUTCString()}`
  1. cookie总大小不超过4094B,总数量不超过20个

  2. 禁止设置永久cookie,应该根据评审设置合理过期时间,可参考一般过期时间段7分钟、30分钟、7天、14天、1个月、2个月

javascript 复制代码
//good
document.cookie=`UI=Joy;domain=.docs.paic.com.cn';path=/#/post;expires=${new Date(new Date().getTime() + 1800000).toUTCString()}`
//bad
document.cookie=`userInfo=Joy;domain=.docs.paic.com.cn';path=/#/post;`

6. 设置合理的domainpath ;浏览器会将domainpath都相同的cookie保存在一个文件里,cookie间用*隔开,合理的设置domainpath既可以满足开发需求,也能非常的有效的减少cookie的范围,继而避免影响其他页面;

javascript 复制代码
//good
document.cookie=`UI=Joy;domain=.docs.paic.com.cn';path=/#/post;expires=${new Date(new Date().getTime() + 1800000).toUTCString()}`
//bad
document.cookie=`userInfo=Joy;expires=${new Date(new Date().getTime() + 1800000).toUTCString()}`

7. 确保cookie有效(不允许存入空值)

javascript 复制代码
//bad
document.cookie=`UI=null;domain=.docs.paic.com.cn';path=/#/post;`
document.cookie=`UI={};domain=.docs.paic.com.cn';path=/#/post;`

8. 明确为业务方自己使用的cookie,用完后应立即删除


5、客观限制

1. 长度限制
  • 大多数浏览器支持最多可达 4096 字节的 Cookie。
2. 数量限制
  • 大多数浏览器只允许每个站点保存 20 个 Cookie。如果试图保存更多的 Cookie,则最先保存的 Cookie 就会被删除。还有些浏览器会对来所有站点的Cookie 总数作出限制,这个限制通常为 300 个
  • 参考数据(由于尚有部分业务条线需要支持ie7和ie8,因此以此版本为示例,其他IE版本暂不列出)
限制类别 限制IE7.0 8.0 Opera Fire Fox Safari Chrome
Cookie个数 每个域名 50个 每个域名 30个 每个域名 50个 没有限制 每个域名 53个
Cookie大小 4095字节 4096字节 4097字节 4097字节 4097字节

二、webStorage使用规范

localStoragesessionStorage 是一种 web 存储方式,存储大小可以达到5M,相比cookie webStorage可以便于我们存储更多的数据,我们可以在使用JavaScript 编写网站和 app 时用它来存储数据到浏览器中。

平时开发中,localStoragesessionStorage 用途是非常多,在我们的开发中发挥着非常重要的作用:

  1. 登录完成后 token 的存储
  2. 用户部分信息的存储,比如 昵称、头像、简介
  3. 一些项目通用参数的存储,例如 某个id、某个参数params
  4. 项目状态管理的持久化,例如 vuex的持久化、redux的持久化
  5. 项目整体的切换状态存储,例如 主题颜色、icon风格、语言标识

1、localStorage与sessionStorage的区别

1. 生存期

  • localStorage数据可以长久地存储,也就意味着浏览器窗口关闭后数据也不会丢失**(localStorage 在 IE 浏览器中,IE8 以上才支持 localStorage)

    localStorage 理论上来说是永久有效的,即不主动清空的话就不会消失,即使保存的数据超出了浏览器所规定的大小,也不会把旧数据清空而只会报错。但需要注意的是,在移动设备上的浏览器或各 Native App 用到的 WebView 里,localStorage 都是不可靠的,可能会因为各种原因(比如说退出 App、网络切换、内存不足等原因)被清空。

  • sessionStorage关闭浏览器窗口后数据会丢失失效

    sessionStorage 的生存期顾名思义,类似于 session,只要关闭浏览器(也包括浏览器的标签页),就会被清空。由于 sessionStorage 的生存期太短,因此应用场景很有限,但从另一方面来看,不容易出现异常情况,比较可靠。

2. 作用域

  • localStorage 只要在相同的协议、相同的主机名、相同的端口下,就能读取/修改到同一份 localStorage 数据;
  • sessionStoragelocalStorage 更严苛一点,除了协议、主机名、端口外,还要求在同一窗口(也就是浏览器的标签页)下。

3. API

localStorage
// 新增/修改
localStorage.setItem(key, value)
// 获取
localStorage.getItem(key)
// 删除
localStorage.removeItem(key)
//清空
localStorage.clear()
sessionStorage
// 新增/修改
sessionStorage.setItem(key, value)
// 获取
sessionStorage.getItem(key)
// 删除
sessionStorage.removeItem(key)
//清空
sessionStorage.clear()

2、命名

同源的两个项目,它们的 localStoragesessionStorage 是互通的。两个项目都需要存储一个 key 为 name 的值,那么这就会造成两个项目的 name 互相顶替的现象,也就是 互相污染现象,例如:

  • 存用户信息会使用 user 作为 key 来存储
  • 主题的时候用 theme 作为 key 来存储
  • 令牌时使用 token 作为 key 来存储

为了在命名上起到隔离作用,推荐几种命名规则:

  1. appKey+缓存key值;
  2. 项目名+缓存key值;
  3. 组织编码+缓存key值;
javascript 复制代码
// good
localStorage.setItem( 'A1007_appkey' , 'xxx')
localStorage.setItem( 'epecker_theme' , 'primary')
localStorage.setItem( 'ARCH_epecker_token' , '3234u390hedidn2eijdws-2e')

// bad
localStorage.setItem( 'appkey' , 'xxx')
localStorage.setItem( 'theme' , 'primary')
localStorage.setItem( 'token' , '3234u390hedidn2eijdws-2e')

3、数据加密

将缓存的数据存在 localStorage、sessionStorage 中,,确实有利于的开发及数据的查看,点击application就可以看到。但是产品一旦上线有些东西不希望被用户看到。这个时候就需要对缓存的数据进行加密了。

1. 网银的国密 js

16 年由网银采购,仅支持非对称加密 sm2 的加解密,不支持签名,摘要和对称加密

注意事项

1、网银 js 的公钥跟其他开发语言和加密平台不一样,由 x,y 组成,比如:

javascript 复制代码
java 的公钥:key="C2C965F4A094CD3B5FD6449E1CC7E068983A5C1317DF35DFDD931AB022BBCF7E C3CA265BC1D52BF9B857074F9C9F34C52D60A9949E883538ACBA0409A6D8049E"

则 js 的公钥为(前一半为 x,后一半为 y):

    X: "C2C965F4A094CD3B5FD6449E1CC7E068983A5C1317DF35DFDD931AB022BBCF7E"

    Y: "C3CA265BC1D52BF9B857074F9C9F34C52D60A9949E883538ACBA0409A6D8049E"

2、国密 java 版本 sm-crypto 公钥加密,js 私钥解密失败,如何解决?

sm-crypto 的密文都做转换为大写,而 js 支持小写,把 sm-crypto 的密文转为小写即可正常解密。

2. 开源实现

支持国密的所有算法,请自行下载

  1. GitHub - JuneAndGreen/sm-crypto: 国密算法js版
  2. GitHub - sickworm/sm-series-crypto: SM2/SM3/SM4 in javascript implementation.

4、webStorage 使用方案

  • 全局使用的东西,共享的东西,永久存储的东西储存在 localstorage 中
  • 不需要永久存储的东西在使用完毕之后 要记得及时清除
  • 如果数据量过大就不要存储在本地了,变为动态获取
  • 可以使用存储量更大的 Indexeddb,不过有兼容性问题
  • 可以在实现方案中对要存储到 storage 中的东西做字数限制

三、其他

1、域名限制

  • 由于浏览器的安全策略,localstorage 是无法跨域的,也无法让子域名继承父域名的 localstorage 数据,这点跟 cookies 的差别还是较大的。

2、数据存储

  • sessionStorage 和 localStorage 不会自动把数据发送给服务器,仅在本地保存。
  • cookie 数据始终在同源的 http 请求中携带(即使不需要),即 cookie 在浏览器和服务器间来回传递。cookie 数据还有路径(path)的概念,可以限制 cookie 只属于某个路径下ker
相关推荐
CodeClimb3 分钟前
【华为OD-E卷-木板 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
咸鱼翻面儿7 分钟前
Javascript异步,这次我真弄懂了!!!
javascript
brrdg_sefg8 分钟前
Rust 在前端基建中的使用
前端·rust·状态模式
m0_7482309432 分钟前
Rust赋能前端: 纯血前端将 Table 导出 Excel
前端·rust·excel
qq_5895681040 分钟前
Echarts的高级使用,动画,交互api
前端·javascript·echarts
弗罗里达老大爷2 小时前
Redis
数据库·redis·缓存
黑客老陈2 小时前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
运维·服务器·前端·网络·安全·web3·xss
正小安2 小时前
Vite系列课程 | 11. Vite 配置文件中 CSS 配置(Modules 模块化篇)
前端·vite
别这么骄傲2 小时前
lookup join 使用缓存参数和不使用缓存参数的执行前后对比
缓存