使用 nodejs express 响应浏览器可以缓存的现有图像文件?
Use nodejs express to respond with existing image file that the browser can cache?
我有一个用 nodejs 和 express(除其他外)构建的小型网络应用程序,它有一个动态调整图像大小的路径(使用 sharp)。路线如下所示:
router.get('/image/:options/:basedir/:dir/:img', utilitiesController.getOptimizedImage);
在实用程序控制器中,我使用 getOptimizedImage 函数检查现有图像,如果存在则返回现有图像内容,如果不存在则执行一些图像处理任务,然后返回生成的图像。
exports.getOptimizedImage = async (req, res) => {
// Parse options from request...
// first, check to see if resized version exists
fs.readFile(processedImgPath, function (err, processedImg) {
if (err) {
//console.log('File does not yet exist.');
// If resized version doesn't exist, check for original
fs.readFile(originImgPath, function (err, originImg) {
if (err) {
// If origin image doesn't exist, return 400.
} else if (w || h) {
// If origin image does exist, process it...
// Once it's processed, return the processed image
res.end(newImg);
return;
}
}
} else {
//
res.end(processedImg);
//res.redirect(existingFileUrl);
return;
}
}
}
此代码有效。我可以这样请求:
<img src="http://example.com/image/w800/foo/bar/imagename.jpg">
...它 returns 调整大小后的图像符合预期。问题似乎是由于使用 res.end() 返回图像的方式,浏览器缓存(在 Chrome 中测试)永远不会存储图像,因此重新加载页面会下载图像新鲜而不是从内存或磁盘加载它。
我也可以使用 res.redirect() 发回现有已处理图像文件的 url,刷新时将缓存该文件,但感觉这样做是错误的方法,因为它最终使用图像处理路径使所有图像请求加倍。
我不想在请求之前处理图像;我特别希望只在第一次请求时处理图像,然后存储处理后的版本以供每次连续引用。我对这些限制条件下的替代方案持开放态度,但希望有人能解释我如何利用当前结构利用浏览器缓存?
您应该在任何 res.end
之前添加用于缓存的 http headers,下面的示例会将 Expires
时间设置为 1 天(86400000 毫秒)。
res.set({
"Cache-Control": "public, max-age=86400",
"Expires": new Date(Date.now() + 86400000).toUTCString()
})
我有一个用 nodejs 和 express(除其他外)构建的小型网络应用程序,它有一个动态调整图像大小的路径(使用 sharp)。路线如下所示:
router.get('/image/:options/:basedir/:dir/:img', utilitiesController.getOptimizedImage);
在实用程序控制器中,我使用 getOptimizedImage 函数检查现有图像,如果存在则返回现有图像内容,如果不存在则执行一些图像处理任务,然后返回生成的图像。
exports.getOptimizedImage = async (req, res) => {
// Parse options from request...
// first, check to see if resized version exists
fs.readFile(processedImgPath, function (err, processedImg) {
if (err) {
//console.log('File does not yet exist.');
// If resized version doesn't exist, check for original
fs.readFile(originImgPath, function (err, originImg) {
if (err) {
// If origin image doesn't exist, return 400.
} else if (w || h) {
// If origin image does exist, process it...
// Once it's processed, return the processed image
res.end(newImg);
return;
}
}
} else {
//
res.end(processedImg);
//res.redirect(existingFileUrl);
return;
}
}
}
此代码有效。我可以这样请求:
<img src="http://example.com/image/w800/foo/bar/imagename.jpg">
...它 returns 调整大小后的图像符合预期。问题似乎是由于使用 res.end() 返回图像的方式,浏览器缓存(在 Chrome 中测试)永远不会存储图像,因此重新加载页面会下载图像新鲜而不是从内存或磁盘加载它。
我也可以使用 res.redirect() 发回现有已处理图像文件的 url,刷新时将缓存该文件,但感觉这样做是错误的方法,因为它最终使用图像处理路径使所有图像请求加倍。
我不想在请求之前处理图像;我特别希望只在第一次请求时处理图像,然后存储处理后的版本以供每次连续引用。我对这些限制条件下的替代方案持开放态度,但希望有人能解释我如何利用当前结构利用浏览器缓存?
您应该在任何 res.end
之前添加用于缓存的 http headers,下面的示例会将 Expires
时间设置为 1 天(86400000 毫秒)。
res.set({
"Cache-Control": "public, max-age=86400",
"Expires": new Date(Date.now() + 86400000).toUTCString()
})