实际操作理解 HTTP 缓存

2024-08-23 01:32

本文主要是介绍实际操作理解 HTTP 缓存,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实际操作理解 HTTP 缓存

网上很多优秀的文章介绍了 HTTP 缓存,但大多是文字内容。

最好结合实际操作,方便更好的理解。

实际操作就需要开启一个 HTTP 服务测试 HTTP 协议,建议使用原生的 Node.js 的 http 模块。

不建议使用 Express Koa Egg 等开发框架,因为它们内置了很多功能,不利于学习原生的 API。

开启 HTTP 服务

创建 app.js

// 使用 nodejs 开启一个 HTTP 服务
const http = require('http')const server = http.createServer()// 任何请求今来,就会触发 request 请求事件,执行处理函数
server.on('request', (req, res) => {res.end('Hello World!')
})server.listen(3000, () => {console.log('running http://localhost:3000')
})

运行:

# 建议使用 nodemon 运行
# npm i -g nodemon
nodemon ./app.js

访问:http://localhost:3000

输出 HTML 内容

// 使用 nodejs 开启一个 HTTP 服务
const http = require('http')const server = http.createServer()// 任何请求今来,就会触发 request 请求事件,执行处理函数
server.on('request', (req, res) => {res.end(`
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Document</title></head><body><h1>HTTP 缓存</h1></body>
</html>
`)
})server.listen(3000, () => {console.log('running http://localhost:3000')
})

输出 html 文件内容

创建 index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Document</title></head><body><h1>HTTP 缓存</h1><p>index.html</p></body>
</html>

修改 app.js

// 使用 nodejs 开启一个 HTTP 服务
const http = require('http')
const fs = require('fs')const server = http.createServer()// 任何请求今来,就会触发 request 请求事件,执行处理函数
server.on('request', (req, res) => {// 每次请求今来都要重新读取该文件const data = fs.readFileSync('./index.html')res.end(data)
})server.listen(3000, () => {console.log('running http://localhost:3000')
})

现在每次请求进来,都要读取磁盘文件 index.html

磁盘读取速度,网络速度都会影响响应的速度。

划分请求路径

此时所有路径的请求都返回同样的 html 内容。

这解释了,请求路径只是一个标识,需要返回什么内容,是服务器处理的。

创建 main.js

console.log('this is main.js')

添加 main.js 引入

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Document</title></head><body><h1>HTTP 缓存</h1><p>index.html</p><script src="./main.js"></script></body>
</html>

修改 app.js

// 使用 nodejs 开启一个 HTTP 服务
const http = require('http')
const fs = require('fs')
const url = require('url')const server = http.createServer()// 任何请求今来,就会触发 request 请求事件,执行处理函数
server.on('request', (req, res) => {// 如果请求 /,则返回 index.html// 如果请求 /main.js,则返回 main.jsconst { pathname: path } = url.parse(req.url)if (path === '/') {const data = fs.readFileSync('./index.html')res.end(data)} else if (path === '/main.js') {const data = fs.readFileSync('./main.js')res.end(data)} else {// 不再受理范围之内的,统一返回 404res.statusCode = 404res.end()}
})server.listen(3000, () => {console.log('running http://localhost:3000')
})

缓存针对的是 GET 请求

缓存一般针对的是静态资源,html css js img 等。

缓存针对的是 GET 请求。

缓存操作目标 - MDN

虽然 HTTP 缓存不是必须的,但重用缓存的资源通常是必要的。然而常见的 HTTP 缓存只能存储 GET 响应,对于其他类型的响应则无能为力。

打印请求日志

查看服务器是否接受了请求,可以确认资源是否使用了缓存。

为请求添加日志打印:

// 使用 nodejs 开启一个 HTTP 服务
const http = require('http')
const fs = require('fs')
const url = require('url')const server = http.createServer()// 任何请求今来,就会触发 request 请求事件,执行处理函数
server.on('request', (req, res) => {// 打印请求日志console.log(`${req.method} ${req.url}`)// 如果请求 /,则返回 index.html// 如果请求 /main.js,则返回 main.jsconst { pathname: path } = url.parse(req.url)if (path === '/') {const data = fs.readFileSync('./index.html')res.end(data)} else if (path === '/main.js') {const data = fs.readFileSync('./main.js')res.end(data)} else {// 不再受理范围之内的,统一返回 404res.statusCode = 404res.end()}
})server.listen(3000, () => {console.log('running http://localhost:3000')
})

再次访问页面,观察控制台,可以看到每次请求都打印了日志。

设置缓存

缓存控制 - MDN

通过定义响应头的 Cache-Control 来设置缓存。

http 模块有两个设置响应头的方法:

// 一次设置一个字段
request.setHeader(name, value)
// 一次可以设置多个字段
request.writeHead(statusCode, {name: value,name: value
})
server.on('request', (req, res) => {// 打印请求日志console.log(`${req.method} ${req.url}`)// 如果请求 /,则返回 index.html// 如果请求 /main.js,则返回 main.jsconst { pathname: path } = url.parse(req.url)if (path === '/') {const data = fs.readFileSync('./index.html')res.end(data)} else if (path === '/main.js') {const data = fs.readFileSync('./main.js')// 设置不缓存res.setHeader('Cache-Control', 'no-store')res.end(data)} else {// 不再受理范围之内的,统一返回 404res.statusCode = 404res.end()}
})

查看浏览器的请求日志,可以看到设置的请求头信息。

设置缓存过期时间

过期机制中,最重要的指令是 “max-age=<seconds>”,表示资源能够被缓存(保持新鲜)的最大时间。相对Expires而言,max-age是距离请求发起的时间的秒数。针对应用中那些不会改变的文件,通常可以手动设置一定的时长以保证缓存有效,例如图片、css、js等静态资源。

server.on('request', (req, res) => {// 打印请求日志console.log(`${req.method} ${req.url}`)// 如果请求 /,则返回 index.html// 如果请求 /main.js,则返回 main.jsconst { pathname: path } = url.parse(req.url)if (path === '/') {const data = fs.readFileSync('./index.html')res.end(data)} else if (path === '/main.js') {const data = fs.readFileSync('./main.js')// 缓存20秒res.setHeader('Cache-Control', 'max-age=20')res.end(data)} else {// 不再受理范围之内的,统一返回 404res.statusCode = 404res.end()}
})

再次访问页面,注意要关闭浏览器的 禁用缓存 (Disable cache)。

查看控制台,发现 main.js 的请求日志没有打印,表示浏览器使用了缓存。

浏览器请求日志中也会显示 (memory cache)表示缓存在内存中,假如内容很大,也可能会缓存在磁盘中。

关于 HTTP 缓存可以参考:

一文读懂http缓存(超详细)

HTTP 缓存 - MDN

这篇关于实际操作理解 HTTP 缓存的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1097964

相关文章

Maven 配置中的 <mirror>绕过 HTTP 阻断机制的方法

《Maven配置中的<mirror>绕过HTTP阻断机制的方法》:本文主要介绍Maven配置中的<mirror>绕过HTTP阻断机制的方法,本文给大家分享问题原因及解决方案,感兴趣的朋友一... 目录一、问题场景:升级 Maven 后构建失败二、解决方案:通过 <mirror> 配置覆盖默认行为1. 配置示

Linux中修改Apache HTTP Server(httpd)默认端口的完整指南

《Linux中修改ApacheHTTPServer(httpd)默认端口的完整指南》ApacheHTTPServer(简称httpd)是Linux系统中最常用的Web服务器之一,本文将详细介绍如何... 目录一、修改 httpd 默认端口的步骤1. 查找 httpd 配置文件路径2. 编辑配置文件3. 保存

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe

如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)

《如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)》:本文主要介绍如何更改pycharm缓存路径和虚拟内存分页文件位置(c盘爆红)问题,具有很好的参考价值,希望对大家有所帮助,如有... 目录先在你打算存放的地方建四个文件夹更改这四个路径就可以修改默认虚拟内存分页js文件的位置接下来从高级-

PyCharm如何更改缓存位置

《PyCharm如何更改缓存位置》:本文主要介绍PyCharm如何更改缓存位置的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录PyCharm更改缓存位置1.打开PyCharm的安装编程目录2.将config、sjsystem、plugins和log的路径

C++ HTTP框架推荐(特点及优势)

《C++HTTP框架推荐(特点及优势)》:本文主要介绍C++HTTP框架推荐的相关资料,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Crow2. Drogon3. Pistache4. cpp-httplib5. Beast (Boos

JSR-107缓存规范介绍

《JSR-107缓存规范介绍》JSR是JavaSpecificationRequests的缩写,意思是Java规范提案,下面给大家介绍JSR-107缓存规范的相关知识,感兴趣的朋友一起看看吧... 目录1.什么是jsR-1072.应用调用缓存图示3.JSR-107规范使用4.Spring 缓存机制缓存是每一

Spring 缓存在项目中的使用详解

《Spring缓存在项目中的使用详解》Spring缓存机制,Cache接口为缓存的组件规范定义,包扩缓存的各种操作(添加缓存、删除缓存、修改缓存等),本文给大家介绍Spring缓存在项目中的使用... 目录1.Spring 缓存机制介绍2.Spring 缓存用到的概念Ⅰ.两个接口Ⅱ.三个注解(方法层次)Ⅲ.

Spring Boot 整合 Redis 实现数据缓存案例详解

《SpringBoot整合Redis实现数据缓存案例详解》Springboot缓存,默认使用的是ConcurrentMap的方式来实现的,然而我们在项目中并不会这么使用,本文介绍SpringB... 目录1.添加 Maven 依赖2.配置Redis属性3.创建 redisCacheManager4.使用Sp

springboot项目redis缓存异常实战案例详解(提供解决方案)

《springboot项目redis缓存异常实战案例详解(提供解决方案)》redis基本上是高并发场景上会用到的一个高性能的key-value数据库,属于nosql类型,一般用作于缓存,一般是结合数据... 目录缓存异常实践案例缓存穿透问题缓存击穿问题(其中也解决了穿透问题)完整代码缓存异常实践案例Red