wake-up-neo.com

flask sieht keine Änderung in der .js-Datei

Ich habe eine Änderung an einer der von mir verwendeten .js - Dateien vorgenommen, und egal, was ich tue, besteht flask) darauf, die letzte Version der Datei aus dem Speicher-Cache abzurufen , ohne die änderung.

Zur Verdeutlichung habe ich folgende Struktur. Alles beginnt mit foo.html

return render_template foo.html

foo.html Enthält ein Formular, das flask mit einigen Daten aufruft und dann eine zweite Vorlage bar.html Zurückgibt:

return render_template bar.html

Diese zweite Vorlage ruft eine .js - Datei auf, die sich im Ordner static befindet. Sie wird jedoch nicht aktualisiert, wenn sich der Code ändert.

Ich erwähne die obige Struktur, weil wenn die .js - Datei auf foo.html Anstelle von bar.html Platziert wurde, Flask would = nimm die neuen Änderungen in der Datei auf, aber in bar.html Flask ignoriert sie vollständig.

Was ist los?

Das einzige, was funktionierte, war auf "Cache deaktivieren" im Browser zu klicken und erneut zu laden.

37
elelias

Letztendlich ist dies ein frustrierendes Browser-Cache-Problem, das behoben werden kann, indem der Browser gezwungen wird, eine "Hard-Refresh" -Verarbeitung durchzuführen. Dies ist ein browser-/betriebssystemabhängiger Tastenanschlag. Im Allgemeinen funktioniert dies jedoch:

  • Windows: Strg + F5
  • Mac: Befehlstaste + Umschalttaste + R
  • Linux: Strg + Umschalt + R

Es gibt andere Dateinamen-Tricks, mit denen dieses Problem vermieden werden kann (in den Kommentaren des OP erwähnt). Diese sind besonders wichtig in der Produktion, in der Sie keine Kontrolle über das Browserverhalten haben.

Für nicht statische Flask Antworten können Sie das cache_control.max_age -Eigenschaft, die dem Browser mitteilen soll, wann die Antwort abläuft, wenn sie zwischengespeichert wird. Wenn Sie beispielsweise einen Flask XHR-Endpunkt haben, der JSON-Daten zurückgibt, können Sie dies tun:

@app.route('/_get_ajax_data/')
def get_ajax_data():
    data = {"hello": "world"}
    response = jsonify(data)
    response.cache_control.max_age = 60 * 60 * 24  # 1 day (in seconds)
    return response

In der Regel können Sie in der Konfiguration Ihres Produktionswebservers auch Standardwerte für bestimmte Ressourcentypen festlegen (z. B. CSS/JS/HTML/JSON/usw.).

Edit 4/1/2019 (unabhängig vom Aprilscherz)

  • Mac/Safari-Tastenanschlag scheint jetzt zu lauten: Cmd + Opt + R (über Kommentare, danke!).
  • In der neuen Antwort von @MarredCheese finden Sie einen sehr eleganten "Dateinamen-Trick", der den Browser zwingt, zwischengespeicherte Kopien für aktualisierte Dateien zu ignorieren.
54
abigperson

Wenn Sie Ihre statischen Assets mit Flask (dies ist normalerweise in einer Entwicklungsumgebung der Fall) bereitstellen, müssen Sie möglicherweise den SEND_FILE_MAX_AGE_DEFAULT Konfigurationswert :

Maximales Alter der Standard-Cache-Steuerung für die Verwendung mit send_static_file() (dem Standard-Handler für statische Dateien) und send_file(), als datetime.timedelta Oder als Sekunden. Überschreiben Sie diesen Wert dateibezogen mit dem Haken get_send_file_max_age() on Flask bzw. Blueprint. Standardmäßig 43200 (12 Stunden).

Um dies zu lösen, müssen Sie lediglich das Wörterbuch app.config Aktualisieren:

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

In diesem Fall speichert Ihr Browser keine statischen Assets, die von Flask bereitgestellt werden.

12
YellowShark

Caching ist normalerweise gut , daher ist es nicht ratsam, es vollständig zu entfernen. Und mit control + F5 oder was auch immer, um eine Hard-Aktualisierung durchzuführen, ist offensichtlich keine skalierbare Lösung, da Sie dies in jedem Browser auf jedem Computer tun müssen.

Eine bessere Idee ist, Browser die Dateien die meiste Zeit zwischenspeichern zu lassen, aber nicht direkt nach der Aktualisierung. Sie können dies erreichen, indem Sie den Zeitpunkt der letzten Aktualisierung der Quelldatei als Argument anhängen zu seiner Pfad-URL. Der Einfachheit halber können Sie den letzten Änderungszeitpunkt für jede Datei im statischen Ordner (oder in allen Unterordnern) verwenden, anstatt jede Datei einzeln zu betrachten.

Python

def dir_last_updated(folder):
    return str(max(os.path.getmtime(os.path.join(root_path, f))
               for root_path, dirs, files in os.walk(folder)
               for f in files))

@app.route('/my-site')
def my_site():
    return render_template('my-site.html',
                           last_updated=dir_last_updated('mydir/static'))

Jinja-Vorlage

<script type="text/javascript" src="/static/my-script.js?u={{ last_updated }}"></script>

HTML-Ergebnis

<script type="text/javascript" src="/static/my-script.js?u=1547330602.31"></script>
8
MarredCheese