JavaScript 页面缓存
1.前言
- 由来:默认环境中,当浏览器重复访问一个资源时,为节省资源与性能,浏览器将其缓存,后续的请求不再从服务器下载该资源,而是直接从本地缓存中读取,默认时没有强制缓存的
- 副作用:当服务器资源更新时,浏览器无法得知,依旧加载的是旧资源
- 缓存类型:强制缓存和协商缓存
2.强制缓存
- 作用:告诉浏览器,强制缓存生效期间,再次拿当前资源不要发请求,直接读取磁盘
- 通过 Expires 设定缓存的过期时间,这个时间是服务器设定的,但是如果客户端与服务端时间不同步,就会产生问题,所以不推荐使用,现在已被后面的 Cache-Control 替代
//强制缓存(设置过期时间)
var expires = new Date()
//1分钟过期
expires.setMinutes(expires.getMinutes() + 1)
res.setHeader('Expires', expires.toUTCString())

- 通过 Cache-Control 设定缓存有效时长(秒),以客户端时间为准,往后计算缓存有效期
res.setHeader("Cache-Control","max-age=7200")

3.协商缓存
- 说明:顾名思义,就是在使用本地缓存之前,向服务器发起GET请求,与之协商当前的缓存是否已经过期,如果已经过期,则下载最新的资源,如果没过期,则读取缓存
- 原理:资源缓存时,附带一个标识(文件最终修改时间,或者文件内容hash),下次请求时然后拿这个标识与服务器的标识 做对比,如果不一致,则返回最新资源,如果一直,则返回返回状态码 304,让浏览器读本地缓存
- 注意:需要设定 Cache-Control 为 no-cache (这里的no-cache含义并不是说不要缓存,而说的是协商缓存,只有设定为no-store才是禁用缓存,设置 max-age 也是可以启用缓存的,只不过此时强制换成优先级比协商缓存高)
- last-modified:通过获取文件最终修改时间作为标识进行判断,下一次请求时,请求头会自动添加 "if-modified-since" 字段并带上之前返回的last-modified的值,服务器就可以知道当前资源的最终修改时间,以此来判断返回的内容。这种方式有2个弊端:第一,文件可能被动过,但是里面内容没变,可能只是重命名,第二,修改时间戳精确到秒,做不到毫秒级的识别判定
//获取文件
var data = fs.readFileSync('./www/index.js')
//获取文件时间
var {mtime} = fs.statSync('./www/index.js')
//设置最终修改时间
res.setHeader("last-modified", mtime.toUTCString())
//开启协商缓存
res.setHeader('Cache-Control','no-cache')
//对比协商缓存的时间,来确定返回结果
var ifModifiedSince = req.headers["if-modified-since"]
if(ifModifiedSince == mtime.toUTCString()){
//告诉浏览器资源未发生变化,让他读缓存
res.statusCode = 304
res.end()
}else{
//返回图片
res.end(data)
}



- Etag:通过文件内容进行hash运算生成字符串(hash运算使用的包名叫 etag),以此带代替last-modified,下一次请求时,请求头会自动添加 "If-None-Match" 字段并带上之前返回的Etag的值。缺点是hash运算计算开销大,影响性能
//获取文件
var data = fs.readFileSync('./www/index.js')
//hash运算生成字符串
var etagContent = etag(data)
//添加到响应头
res.setHeader('etag',etagContent)
//开启协商缓存
res.setHeader('Cache-Control','no-cache')
//判断内容是否发生变化
var ifNoneMatch = req.headers["if-none-match"]
if(ifNoneMatch == etagContent){
//告诉浏览器资源未发生变化,让他读缓存
res.statusCode = 304
res.end()
}else{
//返回图片
res.end(data)
}


4.缓存策略
- HTML文件:HTML文件包含了很多资源的引用,推荐使用协商缓存,当文件修改时才获取最新版本
- 图片,字体文件等静态资源:这类资源要么不改,要么会整体替换掉,推荐使用强制缓存,但是要注意缓存的时间,缓存的东西太多客户端有压力
- 固定URL的js,css文件:这类文件修改频繁,推荐使用协商缓存,当文件修改时才获取最新版本
- 编译后的js,css文件:这里文件常见于脚手架项目,打包编译后文件名是随机变动的,和图片类似,推荐使用强制缓存
5.动态资源链接
- 原理:当一个请求路径不变,但是携带的参数发生变化时,浏览器视为新请求,不读取缓存数据
//在资源链接后面添加版本号(v=100),修改通过这个版本号(v=101),强制客户端更新资源
<script src="./index.js?v=100"></script>
- 全局控制:对资源链接的版本号进行动态拼接,只要修改系统版本号,所有资源强制升级
6.手动清除缓存
- F12->网络->选中请求->清除缓存

- 页面强制重载

7.meta标签中的Cache-Control
- 语法
<meta http-equiv="Cache-Control" content="no-cache">
- 说明:meta标签在HTML文档中用于向浏览器提供关于如何缓存文档的指令。然而,这些指令并不总是被所有浏览器遵循,因为它们的实现可能因浏览器而异。这些指令通常只影响对HTML文档的缓存决策,而不是文档中包含的资源(如CSS、JavaScript文件或图片)的缓存
- 对比HTTP的Cache-Control:HTTP响应头中的Cache-Control指令是由服务器发送的,用于精确控制浏览器(以及其他HTTP缓存)对响应的缓存方式。这些指令对于所有类型的资源(HTML文档、CSS、JavaScript、图片等)都有效,由于HTTP响应头是由服务器直接发送给浏览器的,因此这些指令通常具有比HTML文档中的标签更高的优先级。浏览器在决定是否缓存资源时,会优先考虑HTTP响应头中的Cache-Control指令。
8.离线浏览
- 使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本
- manifest 的技术已被 web 标准废弃,不再推荐使用此功能
JavaScript 页面缓存的更多相关文章
- angular页面缓存与页面刷新
angularJS学习笔记:页面缓存与页面刷新 遇到的问题 现在存在这样一个问题,登录前与登录成功后是同一个页面,只不过通过ngIf来控制哪部分显示,图像信息如下: 所以,整体工作不是很难,无非就 ...
- Flask 页面缓存逻辑,jinja2 过滤器,测试器
回调接入点-页面缓存逻辑 from flask import Flask,request,render_template from werkzeug.contrib.cache import Simp ...
- springboot和redis处理页面缓存
页面缓存是应对高并发的一个比较常见的方案,当请求页面的时候,会先查询redis缓存中是否存在,若存在则直接从缓存中返回页面,否则会通过代码逻辑去渲染页面,并将渲染后的页面缓存到redis中,然后返回. ...
- 设置清除html5页面缓存
设置清除html5页面缓存 html5端设置 meta 标签: <meta http-equiv="Pragma" content="no-cache" ...
- vue中keep-alive,include的指定页面缓存问题
做vue项目时,有时要在某些页面做缓存,而其它页面不要.比如:A:首页,B:获取所有订单页面,C:订单详情页面:从A(首页)进入 B(获取所有订单)时应该不缓存,B(所有订单)进入 C(订单详情)订单 ...
- 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...
- Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解
转载:http://freeloda.blog.51cto.com/2033581/1288553 大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负 ...
- cache-contro页面缓存处理设置
<meta http-equiv="pragma" content="no-cache">,pragma与no-cache用于定义页面缓存,不缓存页 ...
- webform的页面缓存
给页面添加<%@ OutputCache Duration="10" VaryByParam="*"%>标签就可以启用页面缓存. Duration表 ...
- 【WP开发】正确理解页面缓存
注:本文内容面向Runtime App. 在新建项目后,细心观察,你会发现在App类中有以下代码: // TODO: 将此值更改为适合您的应用程序的缓存大小 rootFrame.CacheSize = ...
随机推荐
- Servlet——Tomcat8以前解决中文乱码问题
Request 请求参数中文乱码问题 // 1.解决乱码问题:POST,getReader() request.setCharacterEncoding("UTF-8&quo ...
- 单片机-XIP-外部闪存就地执行代码
声明:此博文所述我未实践,目的是知识整理. 1. 常说的 "单片机的norflash上可以执行代码 " 这句话该如何理解? CPU做取指.译码.执行. 常说的哪些介质可以执行程序 ...
- LeetCode 1438. Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit (绝对差不超过限制的最长连续子数组)
给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit . 如果不存在满足条件的子数组,则返回 ...
- Blazor开发框架Known-V2.0.13
大家好,国庆节快乐,Known又更新了一波功能. 继上个版本以来,一直在完善网站文档.KnownCMS开源项目和解决框架客户提出的一些问题.这期间客户反馈的问题主要如下: 微信模板消息收不到,查其原因 ...
- 16 模块time、datetime、random、hashlib、logging
1. 时间模块time.datetime 在python中,表示时间有三种方式:时间戳 格式化的时间字符串(Format String): '2022-03-01' 时间元组(struct_time) ...
- 使用composer创建项目时报错:Composer could not find the config file?
使用composer创建项目时报错:Composer could not find the config file:C:\Composer ....? 一般报这个错就是composer安装的时候配置了 ...
- linux命令杂记
chmod 777 lixiangj 修改目录为共享权限cd .. 跳转上一级目录cd - 跳转上一次跳转的目录ll 查看目录下所有文件ctrl+L 清除屏幕内容| head -10 只看结果中的前1 ...
- 云原生周刊:Kubernetes v1.30 一瞥 | 2024.3.25
开源项目推荐 Retina Retina 是一个与云无关的开源 Kubernetes 网络可观测平台,它提供了一个用于监控应用程序运行状况.网络运行状况和安全性的集中中心.它为集群网络管理员.集群安全 ...
- docker常用命令与应用
docker入门与docker file介绍 原文地址 docker常用命令 https://blog.csdn.net/leilei1366615/article/details/106267225 ...
- Eclipse中缓存清理
(1)点击tomcat服务器,右键"clean-": (2)删除servers的tomcat服务器下的项目: 控制台显示"Servers窗口":菜单栏--Win ...