使用 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()
})