読者です 読者をやめる 読者になる 読者になる

ぶれすとつーる

だいたいjavascript

レスポンスヘッダのexpiresとリロードの関係

http

レスポンスヘッダのexpiresとリロードの関係あんまり把握してなくてはまったのでメモ

下ごしらえ

expireとcache-controlのmax-ageを適切に設定してレスポンス返すようなコードをかく。

(一応検証に使ったコードは下に記述してあるので面倒な人はそっちをみてください)

リクエストする

リクエストの仕方によって結果代わる

URL直打ち(リンクたどってきたりする自然な動きした時)

f:id:nazomikan:20140114012036p:plain

成功しましたね。

hoge.jsのリクエストが 200 from cache になりました

サーバーに対してステータスコードも聞きにいかずにブラウザのキャッシュから取得した状態です(最も早い)

リロード

次はリロード(F5)します

f:id:nazomikan:20140114012400p:plain

hoge.jsのリクエストが 304 Not Modified になりました

サーバーまでステータスコード聞きにいってます

サーバーまで聞きにいってるのでexpiresの値も更新されます

スーパーリロード

次はスーパーリロード(ctrl + F5)します

f:id:nazomikan:20140114012540p:plain

200で実際にサーバーからレスポンス受け取ってますね(最も遅い状態)

まとめ

スーパーリロードすればexpire無視してサーバーに聞きにいくのは知ってたけどリロードでもステータスコードの確認しにいくんですね

しらずに効いてないと勘違いしてはまったナリ

検証につかったコード

var http = require('http')
  , connect = require('connect')
  , app
  ;
 
app = connect()
  .use(assetsExpire(1000 * 60 * 3))
  .use(connect.static('public'))
  .use(function(req, res){
    res.end(' \
<html> \
<head> \
<script type="text/javascript" src="/hoge.js"></script> \
</head> \
<body>hello world</body> \
</html> \
    ');
  });
 
http.createServer(app).listen(3000);
 
/**
 * 静的ファイル(js, css)のキャッシュ(expireの)設定
 *
 * @param {Number} expire expireの有効期間(単位ms)
 * @return {Function} middleware
 */
 function assetsExpire(expire) {
  var url = require('url')
    , path = require('path')
    ;
 
  // set default value
  expire = expire == null ? (1000 * 60 * 30) : expire;
 
  // connect-middlewareを返す
  return function (req, res, next) {
    var pathname = url.parse(req.url).pathname
      , ext
      , now
      ;
 
    // 拡張子取得
    ext = path.extname(pathname);
    if (!ext) {
      return next();
    }
 
    switch(ext) {
    case '.js':
    case '.css':
      now = (new Date(Date.now() + expire)).toUTCString();
      res.setHeader('Expires', now);
      res.setHeader('Cache-Control', "max-age=" + (expire / 1000));
    default:
      next();
    }
  };
}

gist