Flaskで毎回キャッシュを使わずに読み込ませる
Flask1では静的なコンテンツは指定したディレクトリからしか引き出せないようになっています。デフォルトはstaticです。
/static/css/main.cssのようにアクセスすることでディレクトリ内のファイルが使えます。
この時、ヘッダーに自動的にlast_modifiedを設定しています。そのため、ユーザーの2回目以降のアクセス時にif_modifiedつきでアクセスされ304になり、キャッシュ(Cache)が利用されます。
last_modifiedを自分で設定することで、キャッシュを使わずに毎回読み込ませることが可能になります。
解決策
WSGIアプリケーションのクラスFlaskのインスタンスを作る際に、static_folderを無効にします。
これで、/staticのURLにview関数を登録する部分がスキップされます。
=
/staticのURLにview関数を登録します。
この時、任意の条件にマッチした場合にlast_modifiedを指定します。今回はアクセスされるたびに現在の時刻を指定しています。
=
= None
=
=
return
これで、キャッシュを利用せず毎回読み込ませることが可能になりました。
view関数(static)の補足
endpointを設定してあげることで、view関数の名前(static)を変えてもurl_forが使えるようになります。
...
実装を追う
/staticにアクセスした際のview関数をどこで設定しているのかを確認します。
(コード上で重要でなさそうなところは...で省略しています。)
Flaskのapp.pyの__init__の中で設定されていることがわかります。
# Flask/app.py
...
...
lambda式でsend_static_fileを使用していますが、この関数は
結局のところflask.send_from_directoryです。
# Flask/scaffold.py
...
return
そして結局のところwerkzeug.utils.send_from_directoryです。
# Flask/helpers.py
...
return
そして結局のところwerkzeug.utils.send_fileです。
# werkzeug/utils.py
=
...
return
werkzeug.utils.send_fileはDocstringとコメントを除いて150行くらいの関数です。
**kwargsを使って上から値を渡し続けているので、
flask.send_from_directoryにlast_modified=を設定することで解決できることがわかりました。
# werkzeug/utils.py
...
=
=
...
=
=
...
return
補足
last_modifiedが設定されていない場合はos.stat()を使用し、ファイルの最終内容更新日時を採用しているようです。
# werkzeug/utils.py
=
=
=
=
=
=
=
...
おまけ1 - Cache Busting
更新したファイルがある場合、ファイル名にクエリ文字を追加することでキャッシュは利用されなくなります。
おまけ2 - /static
self.static_url_pathは本当にデフォルトでstaticなのかを確認します。
# Flask/app.py
この時Scaffoldに渡されてself.static_url_pathはstaticだとわかりました。
# Flask/scaffold.py
...
return
=
return f
return None
=
=