当前位置:网站首页>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 initinstall Koa、nodemon
npm i koa -Dnpm i nodemon -gestablish 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 ...
summary
Reference 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 !
边栏推荐
- Cbcgpprogressdlg progress bar used by BCG
- Crystal optoelectronics: ar-hud products of Chang'an dark blue sl03 are supplied by the company
- 太方便了,钉钉上就可完成代码发布审批啦!
- NLP, vision, chip What is the development direction of AI? Release of the outlook report of Qingyuan Association [download attached]
- So this is the BGP agreement
- 数据集划分
- How is the entered query SQL statement executed?
- C # better operation mongodb database
- 2022 version of stronger jsonpath compatibility and performance test (snack3, fastjson2, jayway.jsonpath)
- C # use stopwatch to measure the running time of the program
猜你喜欢

Swagger suddenly went crazy

B2B mall system development of electronic components: an example of enabling enterprises to build standardized purchase, sale and inventory processes

c# .net mvc 使用百度Ueditor富文本框上传文件(图片,视频等)

如何让你的小游戏适配不同尺寸的手机屏幕

ICML 2022 | meta proposes a robust multi-objective Bayesian optimization method to effectively deal with input noise

C # better operation mongodb database

Neural network IOT platform construction (IOT platform construction practical tutorial)

NetCore3.1 Json web token 中间件

C language - Introduction - Foundation - grammar - process control (VII)

Pytoch learning (4)
随机推荐
C # use stopwatch to measure the running time of the program
PHP pseudo original API docking method
In operation (i.e. included in) usage of SSRs filter
B2B mall system development of electronic components: an example of enabling enterprises to build standardized purchase, sale and inventory processes
Delete the characters with the least number of occurrences in the string [JS, map sorting, regular]
漫谈客户端存储技术之Cookie篇
实战模拟│JWT 登录认证
Related concepts of federal learning and motivation (1)
Basic use of kotlin
C language - Introduction - Foundation - grammar - process control (VII)
原来这才是 BGP 协议
Kotlin cycle control
Huawei Nova 10 series supports the application security detection function to build a strong mobile security firewall
Lingyun going to sea | Murong Technology & Huawei cloud: creating a model of financial SaaS solutions in Africa
Cann operator: using iterators to efficiently realize tensor data cutting and blocking processing
15million employees are easy to manage, and the cloud native database gaussdb makes HR office more efficient
ACM组合计数入门
Siemens HMI download prompts lack of panel image solution
Integretee integrates into Moonriver through xcm, bringing enterprise class privacy solutions to its ecosystem
TCP waves twice, have you seen it? What about four handshakes?