代码之家  ›  专栏  ›  技术社区  ›  spencerready

使用nodejs express响应浏览器可以缓存的现有图像文件?

  •  0
  • spencerready  · 技术社区  · 7 年前

    我有一个用nodejs和express(以及其他东西)构建的小webapp,它有一个动态调整图像大小的路径(使用 sharp )。路线如下所示:

    router.get('/image/:options/:basedir/:dir/:img', utilitiesController.getOptimizedImage);
    

    在utilities controller中,我使用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">
    

    。。。并按预期返回调整大小的图像。问题似乎在于,由于使用res.end()返回图像的方式,浏览器缓存(在Chrome中测试)从不存储图像,因此重新加载页面会下载新图像,而不是从内存或磁盘加载。

    我也可以使用res.redirect()发回现有已处理图像文件的url,该文件将在刷新时缓存,但这样做感觉是错误的,因为它最终会使用图像处理路径将所有图像请求加倍。

    我不想在请求之前处理图像;我特别希望只在第一次请求图像时对其进行处理,然后存储一个处理后的版本以引用每个连续的时间。我对这些限制条件下的替代方案持开放态度,但希望有人能解释我如何利用浏览器缓存来实现我当前的结构?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Jack    4 年前

    您应该在任何 res.end ,下面的示例将设置 Expires 时间为1天(86400000ms)。

    res.set({
        "Cache-Control": "public, max-age=86400",
        "Expires": new Date(Date.now() + 86400000).toUTCString()
    })