ブラウザキャッシュの制御cache-control,expires,last-modified,etag,およびプログラミング例について
4602 ワード
ブラウザのキャッシュの意味はネットワークトラフィックを減らすことであり,この目的を達成するために2つの手段が採用されている.
1、クライアントのサーバーに対する要求を減らす
ソリューションは、リソースごとに有効期限を設定することです.
クライアントがリソースを取得した後、ローカルにキャッシュされ、しばらくの間、このリソースを再表示すると、サーバに要求するのではなく、キャッシュされたコンテンツを直接取得します.これに対応したプログラミング手段は,HtppのHeaderでCache-Control:max-age=xxx(秒)またはExpires=Tue,28 Apr 2015 15:50:47 GMT(ここではGMT時間でなければならない)を指定することであり,両者が存在する場合,Cache-Controlが優先される.
2、サーバは重複したコンテンツを転送しません.
解決策は、サーバが各リソースにタグ(またはタイムスタンプ)を付けることです.
これらのタグはリソースとともにクライアントに送信され、クライアントはリクエスト時にキャッシュにすでにこのリソースがある場合は、これらのタグをサーバに返信し、サーバはこれらのタグに基づいて再送信するかどうかを判断します.対応するプログラミング手段は
A.HtppのHeaderでLast-Modified/If-Modified-Sinceを指定し、サービス側送信リソースはLast-Modified、クライアント要求時にIf-Modified-Since、サービス側がリソースが変化していないと判断した場合、304ステータスコードに応答する.どちらもGMTタイムフォーマット
B HtppのHeaderにはETag/If-None-Martchが指定されており、サービス側送信リソースはETag付きであり、クライアント要求時にIf-None-Martchが付き、サービス側がリソースが変化していないと判断した場合、304ステータスコードに応答する.ETagは通常、リソースに対してMD 5コードを計算して得ることができる.
動的データや安全なデータなどのキャッシュに適していないリソースもあります.Cache-Controlにはいくつかのポリシー値があります.
No-cache:キャッシュしないで、クライアントは毎回リソースを再要求します.
Public:クライアントのISP上で確立されたプロキシサーバなど、プロキシサーバ上でキャッシュできます.
Private:クライアントでのみキャッシュでき、プロキシサーバではキャッシュできません
No-store:ファイルに保存しない
また、一般的ではないCach-Controlの設定もあります.例えば、
min-refresh:max-age未満で新しいリソースを要求する
max-stale:期限切れのコンテンツを受け入れることができます
また、CDNがキャッシュ・コンテンツをどのように更新するかに関するポリシー制御もあります.詳細については、http://tools.ietf.org/html/rfc2616#section-14.9を参照してください.
ブラウザのこれらの設定のいくつかの表現:
1)新しいウィンドウを開く値がprivate、no-cache、must-revalidateであれば、新しいウィンドウを開くとサーバに再アクセスします.一方、max-age値が指定されている場合、この値内の時間にサーバに再アクセスすることはありません.たとえば、Cache-control:max-age=5(このページにアクセスしてから5秒以内にサーバに再アクセスしないことを示します)
2)アドレスバーの戻り値がprivateまたはmust-revalidateの場合、最初のアクセス時のみサーバにアクセスし、以降はアクセスしません.値がno-cacheの場合、毎回アクセスします.値がmax-ageの場合、期限が切れるまでアクセスは繰り返しません.
3)後退ボタンで値をprivate、must-revalidate、max-ageとすると再アクセスせず、値をno-cacheとすると毎回繰り返しアクセスする
4)リフレッシュボタンを押すと、値に関係なくCache-control値が「no-cache」の場合、このページにアクセスしてもインターネットの一時記事にページバックアップが残されません.
また、「Expires」の値を指定することでキャッシュにも影響します.たとえば、Expiresの値が過去の時間であることを指定すると、このネットワークにアクセスするときにアドレスバーで繰り返し押すと、毎回繰り返しアクセスします:Expires:Fri、31 Dec 1999 16:00:00:00 GMT例えば、http応答メッセージヘッダ設定をIEにキャッシュするページを禁止する:CacheControl=no-cache Pragma=no-cache Expires=-1 Expiresは良い東であり、サーバ上のページが常に変化している場合は-1に設定します.すぐに期限が切れます.
最後にjava web環境でプログラミングして、純粋なservletで解決すればいいです.
1、クライアントのサーバーに対する要求を減らす
ソリューションは、リソースごとに有効期限を設定することです.
クライアントがリソースを取得した後、ローカルにキャッシュされ、しばらくの間、このリソースを再表示すると、サーバに要求するのではなく、キャッシュされたコンテンツを直接取得します.これに対応したプログラミング手段は,HtppのHeaderでCache-Control:max-age=xxx(秒)またはExpires=Tue,28 Apr 2015 15:50:47 GMT(ここではGMT時間でなければならない)を指定することであり,両者が存在する場合,Cache-Controlが優先される.
2、サーバは重複したコンテンツを転送しません.
解決策は、サーバが各リソースにタグ(またはタイムスタンプ)を付けることです.
これらのタグはリソースとともにクライアントに送信され、クライアントはリクエスト時にキャッシュにすでにこのリソースがある場合は、これらのタグをサーバに返信し、サーバはこれらのタグに基づいて再送信するかどうかを判断します.対応するプログラミング手段は
A.HtppのHeaderでLast-Modified/If-Modified-Sinceを指定し、サービス側送信リソースはLast-Modified、クライアント要求時にIf-Modified-Since、サービス側がリソースが変化していないと判断した場合、304ステータスコードに応答する.どちらもGMTタイムフォーマット
B HtppのHeaderにはETag/If-None-Martchが指定されており、サービス側送信リソースはETag付きであり、クライアント要求時にIf-None-Martchが付き、サービス側がリソースが変化していないと判断した場合、304ステータスコードに応答する.ETagは通常、リソースに対してMD 5コードを計算して得ることができる.
動的データや安全なデータなどのキャッシュに適していないリソースもあります.Cache-Controlにはいくつかのポリシー値があります.
No-cache:キャッシュしないで、クライアントは毎回リソースを再要求します.
Public:クライアントのISP上で確立されたプロキシサーバなど、プロキシサーバ上でキャッシュできます.
Private:クライアントでのみキャッシュでき、プロキシサーバではキャッシュできません
No-store:ファイルに保存しない
また、一般的ではないCach-Controlの設定もあります.例えば、
min-refresh:max-age未満で新しいリソースを要求する
max-stale:期限切れのコンテンツを受け入れることができます
また、CDNがキャッシュ・コンテンツをどのように更新するかに関するポリシー制御もあります.詳細については、http://tools.ietf.org/html/rfc2616#section-14.9を参照してください.
ブラウザのこれらの設定のいくつかの表現:
1)新しいウィンドウを開く値がprivate、no-cache、must-revalidateであれば、新しいウィンドウを開くとサーバに再アクセスします.一方、max-age値が指定されている場合、この値内の時間にサーバに再アクセスすることはありません.たとえば、Cache-control:max-age=5(このページにアクセスしてから5秒以内にサーバに再アクセスしないことを示します)
2)アドレスバーの戻り値がprivateまたはmust-revalidateの場合、最初のアクセス時のみサーバにアクセスし、以降はアクセスしません.値がno-cacheの場合、毎回アクセスします.値がmax-ageの場合、期限が切れるまでアクセスは繰り返しません.
3)後退ボタンで値をprivate、must-revalidate、max-ageとすると再アクセスせず、値をno-cacheとすると毎回繰り返しアクセスする
4)リフレッシュボタンを押すと、値に関係なくCache-control値が「no-cache」の場合、このページにアクセスしてもインターネットの一時記事にページバックアップが残されません.
また、「Expires」の値を指定することでキャッシュにも影響します.たとえば、Expiresの値が過去の時間であることを指定すると、このネットワークにアクセスするときにアドレスバーで繰り返し押すと、毎回繰り返しアクセスします:Expires:Fri、31 Dec 1999 16:00:00:00 GMT例えば、http応答メッセージヘッダ設定をIEにキャッシュするページを禁止する:CacheControl=no-cache Pragma=no-cache Expires=-1 Expiresは良い東であり、サーバ上のページが常に変化している場合は-1に設定します.すぐに期限が切れます.
最後にjava web環境でプログラミングして、純粋なservletで解決すればいいです.
//
public class ImageThumbnailServlet extends HttpServlet {
public static final int SECOND_OF_ONE_DAY = 86400;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uniq = getSourceName(req); // request
contentType="image/jpeg";
String etag=getETag(uniq); // ETag
String ifNoneMatch = req.getHeader("If-None-Match");
if(ifNoneMatch!=null && etag.indexOf(ifNoneMatch)!=-1{ //ETag 304
resp.reset();
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
FileInputStream fileInputSream = getFileInputSream(uniq); //
try {
Long lastModified=getLastModified(uniq);
Long expires=calcExpires();
Long maxAge=calcMaxAge();
resp.setHeader("Content-Type", contentType);
resp.setHeader("Cache-Control","public,max-age="+maxAge);
resp.addDateHeader("Expires", expires);
resp.addDateHeader("Last-Modified",lastModified);
resp.addHeader("ETag",etag);
//
byte[] buffer = new byte[1024];
int byteread;
while ((byteread = fileInputSream.read(buffer)) != -1) {
resp.getOutputStream().write(buffer, 0, byteread);
}
}finally {
fileInputSream.close();
}
}
// if-modified-since, ,
@Override
protected long getLastModified(HttpServletRequest req) {
String uniq = getSourceName(req); // request
return getLastModified(uniq);
}
.......
}