3

大量の画像を管理し、保存してサイズ変更する Web アプリケーションを開発しています。

画像のリクエストは次のようなものです: domain:port/image_id/size

サーバーは image_id を受け取り、そのようなサイズのイメージがまだない場合は、それを作成してファイルシステムに保存します。

したがって、すべて問題なく、サーバーは実行されていますが、サーバーの帯域幅の消費を減らすために、これらの画像を少なくとも 1 日間ブラウザーにキャッシュする必要があります。

いくつかのテストを行いましたが、何も機能していないようです。

応答ヘッダーを作成するために使用するコードは次のとおりです。

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 は常に "image/jpg" や "image/png" のような MIME タイプです。

何かアドバイス?どうもありがとう。

長く生きると繁栄、

d.

4

1 に答える 1

9

私は多くのテストを行い、このキャッシュの問題を管理するのにかなり良いと思われる解決策を見つけました。

基本的に私がしていることは、リクエストを取得し、「if-modified-since」という名前のリクエスト ヘッダーをチェックすることです。見つかった場合、値 (日付) がファイルの変更日と同じであれば、応答は内容のない 304 ステータスになります。この値が見つからない場合、またはファイルの変更日と異なる場合は、ステータス 200 とヘッダー パラメータを含む完全な応答を送信して、ブラウザからさらにアクセスできるようにします。

私が行った動作テストの完全なコードは次のとおりです。

「動作中」とは、最初のリクエストがサーバーからファイルを取得し、次のリクエストが 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

これが役立つことを願っています!

エラーや改善できる点があれば教えてください。

どうもありがとう、ダニエレ

于 2014-03-06T16:27:54.787 に答える