WEBブラウザのキャッシュはネットワークが切れても使えるのかを検証しました。

#　概要
今まで、やらなかったのですが、ある仕事でネットワークが切れても動くシステム(Webアプリ)を作ることになり、クライアントにWEBサーバを入れて、起動させるということを考えたのですが、クライアントの開発は別会社が担当するので、それならブラウザキャッシュに入れて、それを使ったら上手くいくのかという実験をしました。
結果的に上手くいかなかったのですが、ブラウザの設定とか違うやり方で実現ができるという方がいらっしゃったらご指摘ください。

### 検証環境
* macOS Monterey
* Docker Desktop for Mac
* Google Chrome
<br>※PHP+Apache
* 表示用に動画(8MB)と4枚の画像(1枚 1MB程度)を用意

## 1. DockerでWEBサーバを立てる
実験として、Dockerから（PHP+Apache）を入れて、WEBサーバーを立てる
※やり方は省略

## 2. .htaccessにキャッシュを設定
下記のURLを参考にして、.htaccessを設定
https://pocolog.bass-world.net/tech/2017/apache-browser-cache/

.htaccess
※ php、html、css、js、gif、jpg、png、mp4にすべて、3600秒のキャッシュを設定

```
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule \.php$ - [L,E=X_CACHE_PATTERN1:]
    RewriteRule \.html$ - [L,E=X_CACHE_PATTERN2:]
    RewriteRule \.(css|js)$ - [L,E=X_CACHE_PATTERN3:]
    RewriteRule \.(gif|jpe?g|png|mp4)$ - [L,E=X_CACHE_PATTERN4:]

    # For dynamic contents
    Header set Cache-Control "max-age=3600" env=X_CACHE_PATTERN1
    Header unset Expires env=X_CACHE_PATTERN1
    Header unset Last-Modified env=X_CACHE_PATTERN1
    Header unset Etag env=X_CACHE_PATTERN1

    # For HTML files
    Header set Cache-Control "max-age=3600" env=X_CACHE_PATTERN2
    Header set Expires "Mon, 26 Jul 2022 05:00:00 GMT" env=X_CACHE_PATTERN2

    # For CSS,JavaScript files
    Header set Cache-Control "max-age=3600" env=X_CACHE_PATTERN3

    # For Image files
    Header set Cache-Control "max-age=3600" env=X_CACHE_PATTERN4

</IfModule>

```

## 3. index.htmlを作成してDockerを立ち上げる
動画ファイル、画像を読み込んだindex.htmlと動画ファイルと画像ファイルを設定

```
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>ブラウザキャッシュテスト</title>
    <link href="css/style.css"rel="stylesheet">
</head>
<body class="antialiased">
<div>
    <span>
        Apacheで画像、動画、CSS，HTMLにそれぞれブラウザキャッシュ<br />
        Cache-Control "max-age=3600"を設定しました。
    </span>

    <p style="text-align:center">ビデオ表示</p>
    <video autoplay loop muted playsinline
           width="50%"
           height="auto"
           src="video/douga.mp4">
    </video>
    <p style="text-align:center">画像表示</p>
    <img src="img/img.png">
    <img src="img/img_1.png">
    <img src="img/img_2.png">
    <img src="img/img_3.png">
</div>
</body>
</html>

```

上記を作ってから下記でDockerをを起動

```
docker-compose up- d
```
　
## 4. ifconfigコマンドで社内LANのIPアドレスを確認してアクセス
localhostの社内LANのIPアドレスを調べてブラウザからアクセスします。

例えば、僕の社内LANでは下記になりました。

```
http://192.168.1.6/index.html
```

## 5. 社内LAN内にある別のPCからDocker（WEBサーバ）のPCにプラウザからアクセスして検証（Network）で、画面が表示されキャッシュされているかをチェック

Chromeの検証ツール（Networkタブ）で確かめるとPNG、CSS、HTML、MP4のレスポンスヘッダに「Cache-Control “max-age=3600”」が設定されていました。
※3600秒のキャッシュを持つ
画像は動画(mp4)のキャッシュを確認

![スクリーンショット 2022-01-30 17.24.05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669217/ac4018f2-1c07-dac0-bc48-37e65240c0ed.jpeg)


## 6. 検証している別PCのLANを抜いて（WifiもOFF）スターンドアローンでも起動するかを確認

ネットワークが切れても、動画は再生し続けるが、リロードすると

```
「インターネットに接続されていません」
```
が表示されてしまい、画面が表示されなかった(T_T) 

LANを切るのではなくて、dockerを停止させても、結果は接続できずに同じでした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669217/c7a03888-7d20-c890-349c-8c5e939b0f1a.png" width=70%>



## 結果
URLを読み込みに行くと名前解決など、通信が発生するからダメなのかもしれない。
既存のオープンソースのプロキシキャッシュとかで実現できればいいのですが、独自実装が必要になりそう。

# 結論
後から、この記事とか見つけたので、これで実験しようと考えましたが、結局、実現できたとしてもブラウザキャッシュは挙動の制御も難しいそうなので、やはり、クライアントにWEBサーバかProxyサーバを設定してやる実装の提案をすることにしました。

https://www.f5.com/ja_jp/services/resources/white-papers/caching-behavior-of-web-browsers

ご閲覧ありがとうございました。