node.js:具有正确标头的浏览器图像缓存

时间:2014-03-05 15:05:11

标签: node.js response offline-caching http-caching image-caching

我正在开发一个管理大量图像,存储和调整大小的Web应用程序。

图像的请求类似于: 域:端口/ image_id /大小

服务器获取image_id,如果还没有这样大小的图像,它会创建它并将其存储在文件系统上。

所以一切正常,服务器正在运行,但我需要在浏览器中缓存这些图片至少一天,以减少服务器带宽消耗。

我做了几次测试,但似乎没有任何效果。

以下是我用来制作响应标头的代码:

response.writeHead(304, {
          "Pragma": "public",
          "Cache-Control": "max-age=86400",
          "Expires": new Date(Date.now() + 86400000).toUTCString(),
          "Content-Type": contentType});
    response.write(data);
    response.end();

我也尝试过响应状态200。 contentType始终是mime类型,如“image / jpg”或“image / png” data是图像的字节缓冲区。

有什么建议吗? 非常感谢。

活得长久,繁荣,

d

1 个答案:

答案 0 :(得分:8)

我做了很多测试,然后我找到了一个解决这个缓存问题的解决方案。

基本上我所做的是获取请求并检查名为“if-modified-since”的请求标头。 如果我找到它并且值(它是一个日期)与文件的修改日期相同,则响应将是304状态,没有内容。 如果我没有找到这个值或者它与文件的修改日期不同,我会发送状态为200的完整响应和header参数,以便浏览器进一步访问。

以下是我所做的工作测试的完整代码:

with“working”我的意思是第一个请求从服务器获取文件,而下一个请求获得304响应并且不向浏览器发送内容,从内部缓存加载它。

var http    = require("http");
var url     = require("url");
var fs      = require('fs');

function onRequest(request, response) {
    var pathName = url.parse(request.url).pathname;

    if (pathName!="/favicon.ico") {
        responseAction(pathName, request, response);
    } else {
        response.end();
    }
}


function responseAction(pathName, request, response) {
    console.log(pathName);

    //Get the image from filesystem
    var img = fs.readFileSync("/var/www/radar.jpg");

   //Get some info about the file
   var stats = fs.statSync("/var/www/radar.jpg");
   var mtime = stats.mtime;
   var size = stats.size;

   //Get the if-modified-since header from the request
   var reqModDate = request.headers["if-modified-since"];

   //check if if-modified-since header is the same as the mtime of the file 
   if (reqModDate!=null) {
       reqModDate = new Date(reqModDate);
           if(reqModDate.getTime()==mtime.getTime()) {
               //Yes: then send a 304 header without image data (will be loaded by cache)
               console.log("load from cache");
               response.writeHead(304, {
                   "Last-Modified": mtime.toUTCString()
               });

               response.end();
               return true;
        }
    } else {
        //NO: then send the headers and the image
        console.log("no cache");
        response.writeHead(200, {
            "Content-Type": "image/jpg",
            "Last-Modified": mtime.toUTCString(),
            "Content-Length": size
        });

        response.write(img);
        response.end();
        return true;
    }

    //IF WE ARE HERE, THERE IS A PROBLEM...
    response.writeHead(200, {
        "Content-Type": "text/plain",
    });

    response.write("ERROR");
    response.end();
    return false;
}

http.createServer(onRequest).listen(8889);
console.log("Server has started.");

当然,我不想重新发明轮子,这是以前在php中开发的更复杂服务器的基准,这个脚本是这种PHP代码的“移植”:

http://us.php.net/manual/en/function.header.php#61903

我希望这会有所帮助!

如果您发现任何错误或任何可以改进的内容,请告诉我们!

非常感谢, 丹尼尔