68

我对我使用的一个文件进行了更改,.js无论我做什么,flask 都坚持从内存缓存中获取文件的最新版本,而不进行更改。

为了澄清,我有以下结构。一切从foo.html

return render_template foo.html

foo.html里面有一个表单,用一些数据调用烧瓶,然后返回第二个模板bar.html

return render_template bar.html

第二个模板调用了一些.js文件,放置在static文件夹中,但是当代码更改时它不会更新。

我提到上面的结构是因为如果.js放置文件foo.html而不是bar.htmlFlask获取文件上的新更改。但在bar.htmlFlask 中完全忽略了它们。

怎么了?

唯一有效的是在浏览器上单击“禁用缓存”并再次重新加载。

4

5 回答 5

103

最终,这是一个令人沮丧的浏览器缓存问题,可以通过强制浏览器执行“硬刷新”来解决,这将是一个依赖于浏览器/操作系统的击键,但通常这是有效的:

  • 窗口:Ctrl+F5
  • Mac:Cmd+Shift+R
  • Linux:Ctrl+Shift+R

还有其他文件名技巧可以用来避免这个问题(在 OP 的评论中提到)。这些在您无法控制浏览器行为的生产环境中尤其重要。

对于非静态 Flask 响应,您可以设置cache_control.max_age属性,如果响应被缓存,它应该告诉浏览器何时使响应过期。例如,如果您有一个返回 JSON 数据的 Flask XHR 端点,您可以这样做:

@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

您通常还可以在生产 Web 服务器配置中为特定资源类型(例如 CSS/JS/HTML/JSON/等)设置默认值

编辑 2019年 4 月 1日(与愚人节无关)

  • Mac / Safari 击键现在似乎是:Cmd+Opt+R(通过评论,谢谢!)。
  • 请参阅@MarredCheese 的新答案,了解一个非常优雅的“文件名技巧”,以强制浏览器忽略更新文件的缓存副本。
于 2016-12-14T15:43:00.893 回答
39

缓存通常很好,因此不建议完全消除它。并且使用control+F5或其他任何方式进行硬刷新显然不是一个可扩展的解决方案,因为您必须在每台计算机上的每个浏览器中执行此操作。

一个更好的主意是让浏览器在大部分时间缓存文件,但不要在更新后立即缓存。 您可以通过将源文件上次更新的时间作为参数附加到其路径 URL 来实现此目的。为简单起见,您可以对静态文件夹(或任何子文件夹)中的任何文件使用最近的修改时间,而不是单独查看每个文件。

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'))

神社模板

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

HTML 结果

<script type="text/javascript" src="/static/my-script.js?u=1547330602.31"></script>
于 2019-01-12T22:38:41.953 回答
23

如果您使用 Flask 提供静态资产(这通常是开发环境中的情况),那么您可能需要设置SEND_FILE_MAX_AGE_DEFAULT配置值

send_static_file()与(默认静态文件处理程序)和send_file(), asdatetime.timedelta或 as seconds一起使用的默认缓存控制最大年龄。get_send_file_max_age()分别使用 Flask 或 Blueprint上的钩子在每个文件的基础上覆盖此值。默认为 43200(12 小时)。

解决这个问题可以像更新app.config字典一样简单,如下所示:

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

如果你这样做,你的浏览器将不会缓存 Flask 提供的静态资源。

于 2016-12-14T19:22:39.390 回答
1

利用:

if __name__ == '__main__':
    app.config['TEMPLATES_AUTO_RELOAD'] = True
    app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
    app.run(debug=True)

您可以使用F5或更新CTRL + R

于 2020-11-02T16:01:11.630 回答
-3

使用 CTRL+ f5 刷新浏览器

于 2020-05-22T10:43:23.527 回答