55

I have some caching issues. I'm running very small web-application which reads one frame, saves it to the disk and then shows it in browsers window.

I know, it is probably not the best solution, but every time I save this read frame with the same name and therefor any browser will cache it.

I tried to use html meta-tags - no success:

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

Also, I have tried this one (flask-specific):

resp.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
resp.headers["Pragma"] = "no-cache"
resp.headers["Expires"] = "0"

This is how I tried to modify resp headers:

r = make_response(render_template('video.html', video_info=video_info))

r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
r.headers["Pragma"] = "no-cache"
r.headers["Expires"] = "0"

Still both Google Chrome and Safari do caching.

What might be the problem here?

vvvvv
  • 25,404
  • 19
  • 49
  • 81
drsealks
  • 2,282
  • 1
  • 17
  • 34

3 Answers3

83

OK,

finally it worked with this:

@app.after_request
def add_header(r):
    """
    Add headers to both force latest IE rendering engine or Chrome Frame,
    and also to cache the rendered page for 10 minutes.
    """
    r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    r.headers["Pragma"] = "no-cache"
    r.headers["Expires"] = "0"
    r.headers['Cache-Control'] = 'public, max-age=0'
    return r

If you add this, this function will called after each request done. Please,see here

I would be happy, if anyone could explain me why this headers overwriting did not work from the page handler?

Thank you.

drsealks
  • 2,282
  • 1
  • 17
  • 34
  • You told the browser not to cache the response containing the contents of video.html. You need to tell it not to cache the response containing the frame itself. – dirn Dec 03 '15 at 15:16
  • 41
    Note that you are overwriting the `r.headers["Cache-Control"]` from the first line in the second last line. So effectively your response will only have `'public, max-age=0'` set for `Cache-Control` – k-nut Oct 05 '16 at 15:05
  • 12
    Related: Instead of manually specifying the headers, it is now possible with Flask 1.0.2 to access the underlying `cache_control` object of the `Response` instance, then set the [`no_cache`](http://werkzeug.pocoo.org/docs/0.14/datastructures/#werkzeug.datastructures.ResponseCacheControl.no_cache) field to `True` (and other related fields). See https://stackoverflow.com/a/23115561/2745495. – Gino Mempin Dec 10 '18 at 09:04
  • 4
    from MDN docs it looks like `no-store` is the only thing required, and is better practice to put only that when settings `Cache-Control`: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control. I.e. `Cache-Control: no-store` in the server response to prevent caching. – Nick Brady May 04 '20 at 19:07
43

If you have always the same problem, that Flask didn't see the updates in JS and CSS files, that because by default, Flask has as max-age value 12 hours. You can set it to 0 to resolve the problem like this:

app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0

Refer to its documentation for details.

Franklin Yu
  • 8,920
  • 6
  • 43
  • 57
Ilyas
  • 1,976
  • 15
  • 9
4

A combination of app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 in the python file

and hard reload (command + shift + R) of the chrome browser worked for me as it seems Chrome caches the static files