31257


静的なHTMLファイルをGETメソッドで要求したところ、`304(not
modified)`の応答を期待していたのですが`200(cached)`となりました。つまり、ブラウザはサーバへの要求を投げずにブラウザのキャッシュを使用しました。

キャッシュされる元となったリクエストの応答ヘッダを確認すると、`Cache-Control`や`Expires`は存在せず、
**キャッシュの寿命は指定されていませんでした** 。

質問です。

キャッシュの寿命が指定されていない場合、ブラウザはいつになったらサーバに要求を投げるようになるでしょうか。

* * *

確認したブラウザ：FireFox 50.1.0（12/19時点での最新）

## 1\. 最初の要求時（ブラウザがキャッシュを保存する）

要求ヘッダ

[code]

    GET /index.html HTTP/1.1
    Host: www.xxx.net
    User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:50.0) Gecko/20100101 Firefox/50.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: ja,en-US;q=0.7,en;q=0.3
    Accept-Encoding: gzip, deflate, br
    Cookie: （無関係と思われるので省略）
    Connection: keep-alive
    Upgrade-Insecure-Requests: 1
    
[/code]

応答ヘッダ

[code]

    HTTP/1.1 200 OK
    Date: Mon, 19 Dec 2016 03:50:32 GMT
    Server: Apache
    X-Frame-Options: SAMEORIGIN
    X-Content-Type-Options: nosniff
    Strict-Transport-Security: max-age=31536000; includeSubDomains
    Accept-Ranges: bytes
    Etag: W/"2557-1481710774000"
    Last-Modified: Wed, 14 Dec 2016 10:19:34 GMT
    Content-Type: text/html
    Content-Length: 2557
    Connection: close
    
[/code]

* * *

## 2\. 二回目の要求時（ブラウザがキャッシュを表示する）

要求ヘッダ ※見たところ最初の要求と同じ内容

[code]

    GET /index.html HTTP/1.1
    Host: www.xxx.net
    User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:50.0) Gecko/20100101 Firefox/50.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: ja,en-US;q=0.7,en;q=0.3
    Accept-Encoding: gzip, deflate, br
    Cookie: （無関係と思われるので省略）
    Connection: keep-alive
    Upgrade-Insecure-Requests: 1
    
[/code]

応答ヘッダ

[code]

    なし（キャッシュ）
    ※開発ツールを見るとHTTPステータスは「200 OK(cached)」
    
[/code]

##
[![開発者ツールでHTTPステータスを見た様子](https://i.stack.imgur.com/cWn9H.png)](https://i.stack.imgur.com/cWn9H.png)

なお、[英語版stackOverflow](https://stackoverflow.com/questions/1665082/what-is-the-
difference-between-http-status-code-200-cache-vs-status-
code-304)に類似の質問を見つけていますが、英語力不足で知りたいことの記載を見つけることができませんでした…


CC BY-SA 3.0
2016-12-19T04:41:59.180
31232
2016-12-20T06:10:49.710
2017-05-23T12:38:55.307
-1
19759
question
http browser
キャッシュの期限が無指定の場合のブラウザキャッシュの寿命


[MDN](https://developer.mozilla.org/en-
US/docs/Web/HTTP/Caching#Freshness)にそれっぽいことが載ってました。

> The freshness lifetime is calculated based on several headers. If a "Cache-
> control: max-age=N" header is specified, then the freshness lifetime is
> equal to N. If this header is not present, which is very often the case, it
> is checked if an Expires header is present. If an Expires header exists,
> then its value minus the value of the Date header determines the freshness
> lifetime. Finally, if neither header is present, look for a Last-Modified
> header. If this header is present, then the cache's freshness lifetime is
> equal to the value of the Date header minus the value of the Last-modified
> header divided by 10.  
>  The expiration time is computed as follows:  
>  expirationTime = responseTime + freshnessLifetime - currentAge

要するに、サーバからのレスポンスに、

  1. `Cache-control`ヘッダが存在して`max-age=N`のように指定されていたら、キャッシュの寿命はN。
  2. `Cache-control`ヘッダが無くて、`Expires`ヘッダが存在していたら、`<Expiresヘッダの値> - <Dateヘッダの値>`がキャッシュの寿命。
  3. `Cache-control`ヘッダも`Expires`ヘッダも無くて、`Last-Modified`が存在していたら、`(<Dateヘッダの値> - <Last-Modifiedの値>) / 10`がキャッシュの寿命。

質問のケースは3に当てはまるので、キャッシュの寿命がだいたい0.5日くらいと判定されたんじゃないでしょうか。

因みに、[英語版StackOverflow](https://stackoverflow.com/questions/1665082/what-is-
the-difference-between-http-status-code-200-cache-vs-status-
code-304)の方では`Expires`と`Cache-Control: max-age`にしか言及されていないようです。


CC BY-SA 3.0
2016-12-20T05:14:58.660
31257
2016-12-20T05:14:58.660
2017-05-23T12:38:55.307
-1
19437
31232
answer


３つのレスポンス(200(OK),200(cached),304(not modified))が返される一般的な状況は以下のように整理できます。

１）200(OK)  
サーバから要求した情報(たいていはHTMLファイル）が返されてきた事を示します。（キャッシュに情報が無いなどの理由で、キャッシュからデータを取得しなかった）  
要求したURLに対応する情報がサーバからのパケットに入っているので、ブラウザは、それを表示します。  
また、得られた情報をキャッシュとして保存します（httpsでアクセスした情報とか、キャッシュしない指定がされていた場合などでは、保存されません）

２）200(cached)  
有効なキャッシュが存在する場合、サーバにはアクセスせずにキャッシュから情報を取得して表示します。ネットワークを介さないので応答が早いです。

３）304(not modified)  
キャッシュが古くなっている場合、サーバに更新されたデータ（キャッシュの最終更新日よりも後で更新されたデータ）があるかどうかを確認します。（If-
Modified-Sinceリクエストヘッダが用いられます）  
これに対して、サーバが持つデータが更新されていない場合に返されるのが、304(not
modified)で、データ自体は返されません。新しいデータがサーバに無いことが判るので、ブラウザはキャッシュのデータを表示します。  
サーバに新しいデータがあるばあいには、200(OK)で要求したURLのデータ(更新されたもの)を含んだパケットが返されます。返されてきたデータをキャッシュに保存する等の対処は200(OK)のものと同じです。

ブラウザでリロードをした場合にも、サーバに更新されたデータがあるかどうかの確認がされます。  
304(not modified)の応答を期待するのであれば、リロードの操作をするのが良いと思います。


CC BY-SA 3.0
2016-12-20T06:10:25.090
31258
2016-12-20T06:10:25.090
217
31232
answer