85597
RailsのCache-Control設定はデフォルトで以下のようになっています。

```

    Cache-Control: max-age=0, private, must-revalidate
    
```

なぜ以下の値ではなく、上記の設定を採用しているのでしょうか？  
どのような背景があってこのデフォルトを選んでいるかを知りたいです。

```

    Cache-Control: no-store
    
```
CC BY-SA 4.0
2020-12-08T01:55:47.977
72493
2022-01-10T04:29:19.343
2020-12-08T11:44:35.100
3060
34187
question
ruby-on-rails
Rails の Cache-Control 設定のデフォルト値について
まず、

```

    Cache-Control: max-age=0, must-revalidate
    
```

と等価なのは以下の記述です。

```

    Cache-Control: no-cache
    
```

これらは何を表すか、というと、「キャッシュを保管するのはかまわないが、クライアント(ユーザー)から新規にリクエストが来たとき、キャッシュの内容が古くなっていないか確認しろ」という意味になります。

具体的には、 Rails はデフォルトの設定で ETag の rack
が含まれていますが、これを利用してキャッシュのバリデーションを行えます。どういうことかと言うと、クライアントの手元に既にレスポンスキャッシュがあってそれを確認したい場合、クライアントは
`If-None-Match` ヘッダにこの ETag を設定しながら、 `GET`
のリクエストを行います。サーバーは、返すべきレスポンスの内容のハッシュがこの ETag に一致しているかを確認し、一致している場合には `304 Not
Modified` の http レスポンスを返し、実際の内容は省略します。

この `no-cache` 相当の機構を採用している理由ですが、ブラウザが既に受け取ったリクエストを再度送信するのは無駄なので、 ETag
を利用して、必要なければレスポンスの通信量の削減が目的です。

次に、 `private` についてですが、これは 「public なキャッシュ機構はキャッシュするな」という指示子になります。具体的には、 CDN
であったりリバースプロキシ(e.g.
nginx)であったりがあったときに、それらに対してこのレスポンスはキャッシュするべきではない、ということを表します。結果、キャッシュができるのはユーザーが使っているブラウザのみ、になります。  
rails は `session` を使って認証等ができ、同じリクエストでもユーザー毎にレスポンスが変わるので、 public
系のキャッシュは適さないためにこれが付与されているのだと思われます。

最後に、 `no-cache` ではなく、 `max-age=0, must-revalidate` を使っている理由ですが、上記で説明した通り、この
`Cache-Control` ヘッダーはブラウザと CDN などの中間の HTTP プロキシたちが指示の対象になります。 RFC の内容を見てみると、
`max-age` は `Cache-Control` ヘッダ仕様の最初から存在しているが、 `no-cache` と `must-revalidate`
はもうちょっと後に定義されているのが見てとれます。主要ブラウザだけではなく、様々なプロキシたいにおいても動作することを考えて、 `max-age=0,
must-revalidate` を採用しているのだと考えられます。 `no-cache` ないし `must-revalidate`
を解釈しないプロキシが存在したとしても、 `max-age`
さえ解釈してくれれば、キャッシュは使えなかった、という動作になることが期待できるため、といった感じに。

補足として、 `no-store` はキャッシュをどこにも保存しない指示子です。結果、 rails が本来サポートしている `ETag`
によるキャッシュ機構が使えなくなるので、それよりは、ここで説明した通り、 rails のデフォルトを利用するのが良いと思われます。
CC BY-SA 4.0
2022-01-10T04:29:19.343
85597
2022-01-10T04:29:19.343
754
72493
answer