当前位置:网站首页>Practice examples to understand JS strong cache negotiation cache
Practice examples to understand JS strong cache negotiation cache
2022-07-04 20:28:00 【1024 questions】
background
Lead to
Get ready
Launch page
HTTP Cache type
Strong cache
expires
cache-control
Negotiate the cache
Last-Modified,If-Modified-Since
Etag,If-None-Match
summary
backgroundWhether in development or interview ,HTTP Caching is very important , This is reflected in two aspects :
In development : Reasonable use HTTP Caching can improve the performance of front-end pages
During the interview :HTTP Caching is a high-frequency question in an interview
So this article , I don't talk nonsense , I'll go through Nodejs The simple practice of , The most easy to understand HTTP cache , Through this article, you will be able to understand and master it !!!
Lead to Get readyCreate folder cache-study, And prepare the environment
npm init
install Koa、nodemon
npm i koa -Dnpm i nodemon -g
establish index.js、index.html、static Folder
index.html
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="./static/css/index.css" rel="external nofollow" ></head><body> <div class="box"> </div></body></html>
static/css/index.css
.box { width: 500px; height: 300px; background-image: url('../image/guang.jpg'); background-size: 100% 100%; color: #000;}
static/image/guang.jpg
index.js
const Koa = require('koa')const fs = require('fs')const path = require('path')const mimes = { css: 'text/css', less: 'text/css', gif: 'image/gif', html: 'text/html', ico: 'image/x-icon', jpeg: 'image/jpeg', jpg: 'image/jpeg', js: 'text/javascript', json: 'application/json', pdf: 'application/pdf', png: 'image/png', svg: 'image/svg+xml', swf: 'application/x-shockwave-flash', tiff: 'image/tiff', txt: 'text/plain', wav: 'audio/x-wav', wma: 'audio/x-ms-wma', wmv: 'video/x-ms-wmv', xml: 'text/xml',}// Get the type of file function parseMime(url) { // path.extname Get the suffix of the file in the path let extName = path.extname(url) extName = extName ? extName.slice(1) : 'unknown' return mimes[extName]}// Convert the file to the format required for transmission const parseStatic = (dir) => { return new Promise((resolve) => { resolve(fs.readFileSync(dir), 'binary') })}const app = new Koa()app.use(async (ctx) => { const url = ctx.request.url if (url === '/') { // Access the root path and return index.html ctx.set('Content-Type', 'text/html') ctx.body = await parseStatic('./index.html') } else { const filePath = path.resolve(__dirname, `.${url}`) // Set type ctx.set('Content-Type', parseMime(url)) // Set transmission ctx.body = await parseStatic(filePath) }})app.listen(9898, () => { console.log('start at port 9898')})
Launch page Now you can enter... In the terminal nodemon index, See the display below , It means that the service has been started successfully
At this point, you can enter... In the browser link http://localhost:9898/, Open and see the following page , It means that the page is accessed successfully !!!
HTTP There are two common types of caching :
Strong cache : It can be determined by one of these two fields
expires
cache-control( Higher priority )
Negotiate the cache : It can be determined by one of these two pairs of fields
Strong cacheLast-Modified,If-Modified-Since
Etag,If-None-Match( Higher priority )
Next, let's talk about strong caching
expiresWe just need to set the response header expires The time of is the current time + 30s That's it
app.use(async (ctx) => { const url = ctx.request.url if (url === '/') { // Access the root path and return index.html ctx.set('Content-Type', 'text/html') ctx.body = await parseStatic('./index.html') } else { const filePath = path.resolve(__dirname, `.${url}`) // Set type ctx.set('Content-Type', parseMime(url)) // Set up Expires Response head const time = new Date(Date.now() + 30000).toUTCString() ctx.set('Expires', time) // Set transmission ctx.body = await parseStatic(filePath) }})
Then we refresh the front page , We can see that there is one more in the response header of the requested resource expires Field of
also , stay 30s Inside , After we refresh , See the request is to go memory, It means , adopt expires The time effect of setting strong cache is 30s, this 30s within , Resources will go to the local cache , Instead of re requesting
Be careful : Sometimes you Nodejs Code update aging time , However, it is found that the front-end page is still on the time limit of the code , This is the time , You can put this Disabled cache Hook , Then refresh , Cancel... Tick again
Actually cache-control Follow expires The effect is almost the same , It's just that the values of these two fields are different , The former sets the number of seconds , The latter sets the number of milliseconds
app.use(async (ctx) => { const url = ctx.request.url if (url === '/') { // Access the root path and return index.html ctx.set('Content-Type', 'text/html') ctx.body = await parseStatic('./index.html') } else { const filePath = path.resolve(__dirname, `.${url}`) // Set type ctx.set('Content-Type', parseMime(url)) // Set up Cache-Control Response head ctx.set('Cache-Control', 'max-age=30') // Set transmission ctx.body = await parseStatic(filePath) }})
There are too many response headers on the front-end page cache-control This field , And 30s Go to local cache in the , I won't ask the server
Unlike strong caching , Strong caching is within the time limit , Don't go to the server , Only local cache ; The negotiation cache should go through the server , If you request a resource , When you go to the server , If it finds a hit cache, it returns 304, Otherwise, the requested resource is returned , Then how can fortune telling cache ? Let's talk about that
Last-Modified,If-Modified-SinceIn a nutshell :
The first time a resource is requested , The server will take the last modification time of the requested resource as the response header Last-Modified Send the value to the browser and save it in the browser
The second time a resource is requested , The browser will treat the time just stored as the request header If-Modified-Since Value , To the server , The server obtains this time and compares it with the last modification time of the requested resource
If the two times are the same , It means that this resource has not been modified , That is hit cache , Then return 304, If it's not the same , It indicates that this resource has been modified , Cache misses , The modified new resource is returned
// Get file information const getFileStat = (path) => { return new Promise((resolve) => { fs.stat(path, (_, stat) => { resolve(stat) }) })}app.use(async (ctx) => { const url = ctx.request.url if (url === '/') { // Access the root path and return index.html ctx.set('Content-Type', 'text/html') ctx.body = await parseStatic('./index.html') } else { const filePath = path.resolve(__dirname, `.${url}`) const ifModifiedSince = ctx.request.header['if-modified-since'] const fileStat = await getFileStat(filePath) console.log(new Date(fileStat.mtime).getTime()) ctx.set('Cache-Control', 'no-cache') ctx.set('Content-Type', parseMime(url)) // Compare time ,mtime Is the last modification time of the file if (ifModifiedSince === fileStat.mtime.toGMTString()) { ctx.status = 304 } else { ctx.set('Last-Modified', fileStat.mtime.toGMTString()) ctx.body = await parseStatic(filePath) } }})
On the first request , In the response header :
On second request , Request header :
Because the resource has not been modified , Then hit cache , return 304:
At this point, let's modify index.css
.box { width: 500px; height: 300px; background-image: url('../image/guang.jpg'); background-size: 100% 100%; /* Modify here */ color: #333;}
Then let's refresh the page ,index.css Changed , So it will miss the cache , return 200 And new resources , and guang.jpg No modification , The hit cache returns 304:
Actually Etag,If-None-Match Follow Last-Modified,If-Modified-Since Roughly the same , The difference lies in :
The latter is the last modification time of the comparison resource , To determine whether the resource has been modified
The former is to compare the content of resources , To determine whether the resource is modified
How do we compare the content of resources ? We just need to read the content of the resource , Turn into hash value , Just compare it before and after !!
const crypto = require('crypto')app.use(async (ctx) => { const url = ctx.request.url if (url === '/') { // Access the root path and return index.html ctx.set('Content-Type', 'text/html') ctx.body = await parseStatic('./index.html') } else { const filePath = path.resolve(__dirname, `.${url}`) const fileBuffer = await parseStatic(filePath) const ifNoneMatch = ctx.request.header['if-none-match'] // Production content hash value const hash = crypto.createHash('md5') hash.update(fileBuffer) const etag = `"${hash.digest('hex')}"` ctx.set('Cache-Control', 'no-cache') ctx.set('Content-Type', parseMime(url)) // contrast hash value if (ifNoneMatch === etag) { ctx.status = 304 } else { ctx.set('etag', etag) ctx.body = fileBuffer } }})
The verification method is the same as just Last-Modified,If-Modified-Since The same as , I won't repeat it here ...
summaryReference resources https://www.jb51.net/article/254078.htm
The above is the understanding of practical examples js Strong cache negotiate the details of cache , More about js For information about strong cache negotiation cache, please pay attention to other relevant articles on software development network !
边栏推荐
- 数据集划分
- c# .net mvc 使用百度Ueditor富文本框上传文件(图片,视频等)
- Every time I look at the interface documents of my colleagues, I get confused and have a lot of problems...
- Decryption function calculates "task state and lifecycle management" of asynchronous task capability
- 2022 Health Exhibition, health exhibition, Beijing Great Health Exhibition and health industry exhibition were held in November
- Process of manually encrypt the mass-producing firmware and programming ESP devices
- 紫光展锐完成全球首个 5G R17 IoT NTN 卫星物联网上星实测
- Integritee通过XCM集成至Moonriver,为其生态系统带来企业级隐私解决方案
- Anhui Zhong'an online culture and tourism channel launched a series of financial media products of "follow the small editor to visit Anhui"
- Taishan Office Technology Lecture: about the order of background (shading and highlighting)
猜你喜欢
一文搞懂Go语言中文件的读写与创建
Write it down once Net analysis of thread burst height of an industrial control data acquisition platform
Dynamic memory management
应用实践 | 蜀海供应链基于 Apache Doris 的数据中台建设
复杂因子计算优化案例:深度不平衡、买卖压力指标、波动率计算
In the first month of its launch, the tourist praise rate of this campsite was as high as 99.9%! How did he do it?
Aiming at the "amnesia" of deep learning, scientists proposed that based on similarity weighted interleaved learning, they can board PNAS
什么叫内卷?
ICML 2022 | Meta提出鲁棒的多目标贝叶斯优化方法,有效应对输入噪声
Multi table operation - external connection query
随机推荐
In operation (i.e. included in) usage of SSRs filter
How to adapt your games to different sizes of mobile screen
Huawei cloud store homepage banner resource bit application
多表操作-外连接查询
Utilisation de la barre de progression cbcggprogressdlgctrl utilisée par BCG
Niuke Xiaobai month race 7 F question
node强缓存和协商缓存实战示例
Cbcgpprogressdlg progress bar used by BCG
So this is the BGP agreement
应用实践 | 蜀海供应链基于 Apache Doris 的数据中台建设
[problem] Druid reports exception SQL injection violation, part always true condition not allow solution
更强的 JsonPath 兼容性及性能测试之2022版(Snack3,Fastjson2,jayway.jsonpath)
SSRS筛选器的IN运算(即包含于)用法
关于联邦学习和激励的相关概念(1)
[today in history] July 4: the first e-book came out; The inventor of magnetic stripe card was born; Palm computer pioneer was born
Aiming at the "amnesia" of deep learning, scientists proposed that based on similarity weighted interleaved learning, they can board PNAS
Neural network IOT platform construction (IOT platform construction practical tutorial)
Informatics Olympiad 1336: [example 3-1] find roots and children
实战模拟│JWT 登录认证
如何让你的小游戏适配不同尺寸的手机屏幕