HTTP缓存配置详细的一个例子。此示例使用了Node.js来实现EXETC和Last-Modified的相关配置。
HTML部分:
<body>
<h1> HTTP 缓存 </h1>
<h2> 强制缓存 </h2>
<!-- <img width = "100" src = "./img/01.jpg" alt = "01.jpg" > -->
<hr>
<h2> 协商缓存 </h2>
<!-- <img width = "100" src = "./img/02.jpg" alt = "02.jpg" > -->
</body>
app.js部分:
// 测试案例
const http = require('http');
const fs = require('fs');
const url = require('url');
const etag = require('etag');
let serve = http.createServer((req, res) => {
const { pathname } = url.parse(req.url);
if (pathname === '/') {
const data = fs.readFileSync('./index.html');
res.end(data);
} else if (pathname === '/img/01.jpg') {
const data = fs.readFileSync('./img/01.jpg');
res.writeHead(200, {
Expires: new Date('2021-8-5 00:21:49').toUTCString()
});
res.end(data);
} else if (pathname === '/img/02.jpg') {
const data = fs.readFileSync('./img/02.jpg');
const etagContent = etag(data);
const ifNoneMatch = req.headers['if-none-match'];
if (ifNoneMatch === etagContent) {
res.statusCode = 304;
res.end();
return;
}
res.setHeader('etag', etagContent);
res.setHeader('Cache-Control', 'no-cache');
res.end(data);
} else {
res.statusCode = 404;
res.end();
}
});
serve.listen(3000, () => {
console.log("http://localhost:3000");
});
请注意这个例子只是一个基本的示例,实际的配置可能需要根据你的项目需求来调整。代码中的etag库可以通过npm获取(npm install etag)。
理论上,这个例子中你可以添加任意数量的图片,只要你有足够的存储空间来保存这些图片即可。每当你想添加一张新的图片,只需要在服务器的代码中添加一个新的else if语句来处理那张图片的路径,并在你的HTML文件中给那张图片添加一个新的标签。
然而,如果你想添加大量的图片,这种方法可能会变得相当繁琐和低效。你可能需要修改你的代码来更灵活地处理大量的图片路径,比如,你可以遍历一个目录来发送目录中的所有图片,或者你可以使用一个数据库来管理你所有的图片和它们的路径等等。
需要注意的是,无论你的服务器能支持多少图片,最重要的是你的服务器的性能能否承受这么大的负载,并且能否在浏览器请求这些图片的时候快速地提供服务。这也是为什么我们会使用HTTP缓存等技术来提升服务器的性能和提供更好的用户体验。
对于处理大量图片的路径的问题,我们可以使用Node.js中的fs模块通过readdir()或者readdirSync()函数读取文件目录来获取文件列表。这样一来,我们就可以使用一个循环来处理所有的图片,而不是为每一张图片单独写一个路径。
以下为使用fs.readdirSync()函数读取文件夹并处理图片路径的范例代码:
...
const path = require('path');
...
let serve = http.createServer((req, res) => {
const { pathname } = url.parse(req.url);
if (pathname === '/') {
const data = fs.readFileSync('./index.html');
res.end(data);
} else {
//获得路径下的文件名数组
const imgFiles = fs.readdirSync('./img');
for (let imgFile of imgFiles) {
//如果路径里包含文件名
if (pathname.includes(imgFile)) {
const data = fs.readFileSync(./img/${imgFile});
const etagContent = etag(data);
const ifNoneMatch = req.headers['if-none-match'];
if (ifNoneMatch === etagContent) {
res.statusCode = 304;
res.end();
return;
}
res.setHeader('etag', etagContent);
res.setHeader('Cache-Control', 'no-cache');
res.end(data);
return;
}
}
//如果没有符合的文件则返回404错误
res.statusCode = 404;
res.end();
}
});
serve.listen(3000, () => {
console.log("http://localhost:3000");
});
下面详细介绍一下:fs.readdir(path, callback)和fs.readdirSync(path)。这两个函数都用于获取指定目录下的所有文件以及文件夹名称,并返回一个包含文件名和文件夹名的数组。
对于fs.readdir(path, callback),它是异步的,即它在返回结果前不会阻塞其余的代码执行。此函数需要两个参数:一个是文件路径,另一个是回调函数。回调函数需要两个参数:一个是错误对象(如果没有错误,则为null),另一个是文件名或文件夹名的数组。
对于fs.readdirSync(path),它是同步的,它会阻塞其余的代码直至返回结果。此函数只需要一个参数就是文件路径,它会返回一个包含文件名或文件夹名的数组。
以下是两个函数的使用示例:
const fs = require('fs');
// 使用fs.readdir(path, callback)
fs.readdir('./img', (err, files) => {
if (err) {
console.log("读取文件夹发生错误", err);
} else {
console.log("异步读取:", files);
}
});
// 使用fs.readdirSync(path)
let files = fs.readdirSync('./img');
console.log("同步读取:", files);
//运行该代码,如果img文件夹存在,你将看到类似的输出:
同步读取: [ '01.jpg', '02.jpg' ]
异步读取: [ '01.jpg', '02.jpg' ]
这两个数组就包含了img文件夹下的所有文件名。
在上述代码中,我们先读取文件夹中的所有文件名并以数组的形式存储,然后在一个循环中判断用户请求的路径是否包含数组中的任意一个文件名,如果包含则进行处理。如果没有找到符合的文件名,则返回404错误。这样,我们就可以在不改变HTML文件的情况下,动态地加入或删除图片。
以上就是文章全部内容了,如果喜欢这篇文章的话,还希望三连支持一下,感谢!