ブラウザのキャッシュについて、私はこれまでこの分野の多くの情報を読んできましたが、常に運用とメンテナンスが対処すべきものだと思っていました。自分でやったことがないので、深く理解していません。忘れがちです
最近、nodejs について調べました。静的サーバーの実行について少し詳しく理解したので、メモを取りました
読んだ記事
キャッシュ制御、有効期限、最終更新日
キャッシュのプロセス
nodejsの簡単な実装
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=zh-cn
http://www.laruence.com/2010/03 /05/1332.html
http://www.alloyteam.com/2012/03/web-cache-2-browser-cache/
https://cnodejs.org/topic/4f16442ccae1f4aa27001071
Expires
Expires ヘッダー フィールドには日付と時刻が指定され、応答はその日付と時刻になり、それ以降は無効とみなされます。期限切れのキャッシュ エントリは通常キャッシュされません
Expires フィールドには次の形式の値が入ります: "Expires: Sun, 08 Nov 2009 03:37:26 GMT" たとえば、時間を 30 日に設定したい場合、これは次のようになります。は、nodejs の新しい日付です (new Date().getTime()+60*60*24*30).toUTCString()
これは Last-Modified と組み合わせて使用する必要があります
リクエストされたファイルがキャッシュされている場合ブラウザ、次回リクエストの際、ブラウザにアドレスを直接入力するとリクエストは送信されません
Ctrl+Rを強制的に押すと、サーバーはリクエストヘッダーのLast-Modifiedを比較してリクエストを送信します。変更がない場合は、クライアントのようにファイルを返さないため、クライアントは返されたファイルが 304 であることを認識すると、そのファイルを読み取ります。ブラウザから
http/1.0からサポートされています
cache-controlがある場合、max-ageはExpiresをオーバーライドします
cache-control
no-cache
これは理解しやすいです、つまり、No caching
max-age
は秒数に設定されています。今回は、リクエストはサーバーに送信されません。強制的に更新された場合は、Expires と同じ 304 が返されます。
形式は次のとおりです。 Cache-Control: max-age=315360000
public
応答はキャッシュされ、複数のユーザー間で共有されます
プライベート
応答はプライベートにのみキャッシュされ、ユーザー間で共有することはできません。たとえば、POST フォームが送信されると、入力されたコンテンツを保持し、各ユーザーのキャッシュを示すのに役立ちます
Last-Modified
形式は次のとおりです last-modified:Thu , 23 Jul 2015 08:50:29 GMT
これは応答ヘッダーに設定されます
if-modified-since
ブラウザはサーバーからLast-Modifiedを受信し、記録します次回リクエストを送信するとき、If-modified-since がリクエスト ヘッダーに含まれているため、その値は前回の Last-Modified によって返された値になります
キャッシュ プロセス
これは個人的な理解にすぎず、実際とは異なる場合があります。静的サーバー側はnodejsで処理されます
1. ブラウザが初めてアクセスするときは、すべてのファイルをダウンロードする必要があります
3. ブラウザに再度アクセスする場合、図に示すように、ブラウザにアドレスを直接入力すると、キャッシュされたファイルのリクエストは送信されません。強制更新 (ctrl+r) を実行すると、リクエストがサーバーに送信され、リクエスト ヘッダーで渡された if-modified-since に基づいてファイルの最終更新日が比較されます。図に示すように、ファイルの内容は返されず、ステータス コード 304 が返されます
nodejs の簡単な実現
var http = require("http");var fs = require("fs");var url = require("url");var querystring = require("querystring");http.createServer(function(req,res){ var gurl = req.url, pathname = url.parse(gurl).pathname; if( pathname.indexOf("favicon.ico")>=0){ var ico = fs.readFileSync("./favicon.ico"); res.writeHead(200,{ "Content-Type" : "image/x-icon" }) res.end(ico); return; } if(pathname.indexOf("/static/")==0){ var realPath = __dirname + pathname; dealWithStatic(pathname,realPath,res,req); return; }}).listen(5555);function dealWithStatic(pathname,realPath,res,req){ fs.exists(realPath,function(exists){ if(!exists){ res.writeHead(404,{ "Content-Type" : "text/html" }); res.end("not find!!!"); }else{ var mmieString = /\.([a-z]+$)/i.exec(pathname)[1], cacheTime = 2*60*60, mmieType; switch(mmieString){ case "html" : case "htm" : case "xml" : mmieType = "text/html"; break; case "css" : mmieType = "text/css"; break; case "js" : mmieType = "text/plain"; break; case "png" : mmiType = "image/png"; break; case "jpg" : mmiType = "image/jpeg"; break; default : mmieType = "text/plain"; } var fileInfo = fs.statSync(realPath), lastModied = fileInfo.mtime.toUTCString(), modifiedSince = req.headers['if-modified-since'] if(modifiedSince && lastModied == modifiedSince){ res.writeHead(304,"Not Modified"); res.end(); return; } fs.readFile(realPath,function(err,file){ if(err){ res.writeHead(500,{ "Content-Type" : "text/plain" }); res.end(err); }else{ var d = new Date(); var expires = new Date(d.getTime()+10*60*1000); res.writeHead(200,{ "Content-Type" : mmieType, "Expires" : expires.toUTCString(), "Cache-Control" : "max-age=" + cacheTime, "Last-Modified" : lastModied }); res.end(file); } }); } });}