Browser caching issues in flask

27,970

Solution 1

Setting the cache to be max-age=0 fixed it.

@app.after_request
def add_header(response):
    """
    Add headers to both force latest IE rendering engine or Chrome Frame,
    and also to cache the rendered page for 10 minutes.
    """
    response.headers['X-UA-Compatible'] = 'IE=Edge,chrome=1'
    response.headers['Cache-Control'] = 'public, max-age=0'
    return response

Solution 2

To stop browser caching on these sort of pages you need to set some HTTP response headers.

Cache-Control: no-cache, no-store
Pragma: no-cache

Once you do this then the browser wont cache those pages. I dont know how to do this with "flask" so I will leave that as an exercise for you :)

This question shows how to add a response header Flask/Werkzeug how to attach HTTP content-length header to file download

Share:
27,970

Related videos on Youtube

The Internet
Author by

The Internet

yea

Updated on January 29, 2020

Comments

  • The Internet
    The Internet over 4 years

    I have built a website using flask (www.csppdb.com). Sometimes when I log in as one user, log out, then login as another user I still see pages from the first user I logged in as. This problem is immediately fixed when the page is refreshed. I think this is called "caching" if I am not mistaken. Is there any way I could disable this on a site wide level so that every page that is visited needs a new refresh?

    It would be like sharing your computer with a friend. He logs into Facebook, then logs out. Now you log in on his computer and you see his profile... (awkward). After you refresh the page the problem is fixed.

    Here is some of my code. I was using flask-login but I then tried to "roll my own"

    from flask.ext.mysql import MySQL
    import os
    from flask import Flask, request, jsonify, session, url_for, redirect, \
         render_template, g, flash
    from data import *
    from werkzeug import check_password_hash, generate_password_hash
    import config
    
    app = Flask(__name__)
    mysql = MySQL()
    
    app.config['MYSQL_DATABASE_HOST'] = os.environ['MYSQL_DATABASE_HOST'] if 'MYSQL_DATABASE_HOST' in os.environ else config.MYSQL_DATABASE_HOST
    app.config['MYSQL_DATABASE_PORT'] = os.environ['MYSQL_DATABASE_PORT'] if 'MYSQL_DATABASE_PORT' in os.environ else config.MYSQL_DATABASE_PORT
    app.config['MYSQL_DATABASE_USER'] = os.environ['MYSQL_DATABASE_USER'] if 'MYSQL_DATABASE_USER' in os.environ else config.MYSQL_DATABASE_USER
    app.config['MYSQL_DATABASE_PASSWORD'] = os.environ['MYSQL_DATABASE_PASSWORD'] if 'MYSQL_DATABASE_PASSWORD' in os.environ else config.MYSQL_DATABASE_PASSWORD
    app.config['MYSQL_DATABASE_DB'] = os.environ['MYSQL_DATABASE_DB'] if 'MYSQL_DATABASE_DB' in os.environ else config.MYSQL_DATABASE_DB
    
    mysql.init_app(app)
    
    if 'SECRET_KEY' in os.environ: app.config['SECRET_KEY'] = os.environ['SECRET_KEY']
    else: app.config['SECRET_KEY'] = os.urandom(24)
    
    def connect_db(): return mysql.connect()
    
    def check_auth():
        g.user = None
        if 'username' in session:
            g.user = get_user(session['username'])
            return
        return redirect(url_for('login'))
    
    @app.route('/')
    def home(): 
        if 'username' in session: return redirect(url_for('main'))
        return render_template('home.html')
    
    def connect_db(): return mysql.connect()
    
    @app.teardown_request
    def teardown_request(exception):
        if exception: print exception
        g.db.close()
    
    @app.before_request
    def before_request():
        print session.keys(), session.values()
        print("before request")
        print ('username' in session, "in session?")
        g.db = connect_db()
        g.user = None
        if "username" in session:
            g.user = get_user(session['username'])
    
    
    @app.route('/login/', methods=['GET', 'POST'])
    def login():
        """Logs the user in."""
        if 'username' in session:
            return redirect(url_for('main'))
    
        error = None
        if request.method == 'POST':
            print("login hit")
            user = get_user(request.form['username'])
            if user is None:
                error = 'Invalid username'
                print error
            elif not check_password_hash(user.password, request.form['password']):
                error = 'Invalid password'
                print error
            else:
                flash('You were logged in')
                print "logged in"
                session['username'] = request.form['username']
                g.user = request.form['username']
                print error, "error"
                return redirect(url_for('main'))
    
        return render_template('login.html', error=error)
    
    • Denis
      Denis over 11 years
      Nobody can't say you anything before you don't place here any code, for example login and logout views and example of template where this bug.
    • The Internet
      The Internet over 11 years
      @Denis, please see the attached code
    • MalphasWats
      MalphasWats over 11 years
      How does a user log out? The code isn't included and I wondered how you were handling the session.
    • The Internet
      The Internet over 11 years
      logout is just popping the user out of the session. session.pop('username', None)
  • cowls
    cowls over 11 years
    This http header should be set in the http response from the server
  • cowls
    cowls over 11 years
    @Dave updated answer to include a question that shows how to add response headers
  • Nick Brady
    Nick Brady about 4 years
    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: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Cont‌​rol. I.e. Cache-Control: no-store in the server response to prevent caching. max-age=0 is implied.