实际操作理解 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

相关文章

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Linux修改pip和conda缓存路径的几种方法

《Linux修改pip和conda缓存路径的几种方法》在Python生态中,pip和conda是两种常见的软件包管理工具,它们在安装、更新和卸载软件包时都会使用缓存来提高效率,适当地修改它们的缓存路径... 目录一、pip 和 conda 的缓存机制1. pip 的缓存机制默认缓存路径2. conda 的缓

Redis解决缓存击穿问题的两种方法

《Redis解决缓存击穿问题的两种方法》缓存击穿问题也叫热点Key问题,就是⼀个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击,本文给大家介绍了Re... 目录引言解决办法互斥锁(强一致,性能差)逻辑过期(高可用,性能优)设计逻辑过期时间引言缓存击穿:给

Go语言中最便捷的http请求包resty的使用详解

《Go语言中最便捷的http请求包resty的使用详解》go语言虽然自身就有net/http包,但是说实话用起来没那么好用,resty包是go语言中一个非常受欢迎的http请求处理包,下面我们一起来学... 目录安装一、一个简单的get二、带查询参数三、设置请求头、body四、设置表单数据五、处理响应六、超

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

一文详解Nginx的强缓存和协商缓存

《一文详解Nginx的强缓存和协商缓存》这篇文章主要为大家详细介绍了Nginx中强缓存和协商缓存的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、强缓存(Strong Cache)1. 定义2. 响应头3. Nginx 配置示例4. 行为5. 适用场景二、协商缓存(协

Golang基于内存的键值存储缓存库go-cache

《Golang基于内存的键值存储缓存库go-cache》go-cache是一个内存中的key:valuestore/cache库,适用于单机应用程序,本文主要介绍了Golang基于内存的键值存储缓存库... 目录文档安装方法示例1示例2使用注意点优点缺点go-cache 和 Redis 缓存对比1)功能特性

如何使用Docker部署FTP和Nginx并通过HTTP访问FTP里的文件

《如何使用Docker部署FTP和Nginx并通过HTTP访问FTP里的文件》本文介绍了如何使用Docker部署FTP服务器和Nginx,并通过HTTP访问FTP中的文件,通过将FTP数据目录挂载到N... 目录docker部署FTP和Nginx并通过HTTP访问FTP里的文件1. 部署 FTP 服务器 (

Qt实现发送HTTP请求的示例详解

《Qt实现发送HTTP请求的示例详解》这篇文章主要为大家详细介绍了如何通过Qt实现发送HTTP请求,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、添加network模块2、包含改头文件3、创建网络访问管理器4、创建接口5、创建网络请求对象6、创建一个回复对

springMVC返回Http响应的实现

《springMVC返回Http响应的实现》本文主要介绍了在SpringBoot中使用@Controller、@ResponseBody和@RestController注解进行HTTP响应返回的方法,... 目录一、返回页面二、@Controller和@ResponseBody与RestController