繁体   English   中英

烧瓶没有看到 .js 文件中的变化

[英]flask does not see change in .js file

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

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

return render_template foo.html

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

return render_template bar.html

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

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

怎么了?

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

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

  • 视窗: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/等)设置默认值

编辑 4/1/2019 (与愚人节无关)

  • Mac / Safari 击键现在显示为:Cmd+Opt+R(通过评论,谢谢!)。
  • 请参阅@MarredCheese 的新答案,了解一个非常优雅的“文件名技巧”,以强制浏览器忽略更新文件的缓存副本。

缓存通常好的,因此不建议完全消除它。 并且使用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>

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

默认缓存控制 max age 与send_static_file() (默认静态文件处理程序)和send_file() ,作为datetime.timedelta或作为秒。 分别使用 Flask 或 Blueprint 上的get_send_file_max_age()挂钩在每个文件的基础上覆盖此值。 默认为 43200(12 小时)。

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

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

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

用:

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

您可以使用F5CTRL + R进行更新。

使用 CTRL+ f5 刷新浏览器

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM