简体   繁体   English

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

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

I made a change on one of the .js files that I use and no matter what I do, flask insists on picking up, from memory cache, the last version of the file, without the change.我对我使用的其中一个.js文件进行了更改,无论我做什么,flask 都坚持从内存缓存中获取文件的最新版本,而不进行更改。

To clarify, I have the following structure.为了澄清,我有以下结构。 It all starts with foo.html一切从foo.html开始

return render_template foo.html

foo.html has a form inside that calls flask with some data and then returns a second template bar.html : foo.html里面有一个表单,它用一些数据调用烧瓶,然后返回第二个模板bar.html

return render_template bar.html

This second template calls some .js file, placed in the static folder, but it doesn't update when the code changes.第二个模板调用一些.js文件,放置在static文件夹中,但它不会在代码更改时更新。

I mention the structure above because if the .js file was placed on foo.html instead of bar.html then Flask would pick up the new changes on the file.我提到上面的结构是因为如果.js文件放在foo.html而不是bar.html那么 Flask在文件上获取新的更改。 But in bar.html Flask completely ignores them.但是在bar.html Flask 中完全忽略了它们。

What is happening?怎么了?

The only thing that worked was to click on "disable cache" on the browser and reload again.唯一有效的是点击浏览器上的“禁用缓存”并重新加载。

Ultimately this is a frustrating browser cache issue, which can be solved by forcing the browser to do a "hard refresh", which is going to be a browser/OS dependent keystroke, but generally this works:最终,这是一个令人沮丧的浏览器缓存问题,可以通过强制浏览器执行“硬刷新”来解决,这将是浏览器/操作系统相关的按键,但通常这是有效的:

  • Windows: Ctrl+F5视窗:Ctrl+F5
  • Mac: Cmd+Shift+R Mac:Cmd+Shift+R
  • Linux: Ctrl+Shift+R Linux:Ctrl+Shift+R

There are other filename tricks one can use to avoid this issue (mentioned in comments of the OP).还有其他文件名技巧可以用来避免这个问题(在 OP 的评论中提到)。 These are especially important in production where you have no control over browser behavior.这些在您无法控制浏览器行为的生产环境中尤为重要。

For non-Static Flask responses you can set the cache_control.max_age property, which should tell the browser when to expire the response if it is cached.对于非静态 Flask 响应,您可以设置cache_control.max_age属性,如果它被缓存,它应该告诉浏览器何时使响应过期。 For instance if you have a Flask XHR endpoint that returns JSON data you could do this:例如,如果您有一个返回 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

You typically can also set default values in your production web server configuration for specific resource types (eg CSS/JS/HTML/JSON/etc)您通常还可以在生产 Web 服务器配置中为特定资源类型(例如 CSS/JS/HTML/JSON/等)设置默认值

Edit 4/1/2019 (unrelated to April Fools day)编辑 4/1/2019 (与愚人节无关)

  • Mac / Safari keystroke now appears to be: Cmd+Opt+R (via comments, thanks!). Mac / Safari 击键现在显示为:Cmd+Opt+R(通过评论,谢谢!)。
  • See the new answer from @MarredCheese for a very elegant "filename trick" to force the browser to ignore cached copies for updated files.请参阅@MarredCheese 的新答案,了解一个非常优雅的“文件名技巧”,以强制浏览器忽略更新文件的缓存副本。

Caching is normally good , so it's not advisable to eliminate it entirely.缓存通常好的,因此不建议完全消除它。 And using control + F5 or whatever to do a hard refresh is obviously not a scalable solution since you have to do it in every browser on every computer.并且使用control + F5或其他任何方式进行硬刷新显然不是一个可扩展的解决方案,因为您必须在每台计算机的每个浏览器中执行此操作。

A better idea is to let browsers cache the files most of the time, but not right after they've been updated.一个更好的主意是让浏览器在大部分时间缓存文件,而不是在更新后立即缓存。 You can achieve this by appending the time that the source file was last updated as an argument to its path URL.您可以通过将源文件上次更新的时间作为参数附加到其路径 URL 来实现此目的。 For simplicity, you can use the most recent modification time for any file in the static folder (or any subfolders), as opposed to looking at each file individually.为简单起见,您可以对静态文件夹(或任何子文件夹)中的任何文件使用最近的修改时间,而不是单独查看每个文件。

Python 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 Template金贾模板

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

HTML Result HTML 结果

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

If you are serving your static assets with Flask (this is typically the case in a development environment), then you might need to set the SEND_FILE_MAX_AGE_DEFAULT configuration value :如果您使用 Flask 提供静态资产(这通常是在开发环境中的情况),那么您可能需要设置SEND_FILE_MAX_AGE_DEFAULT配置值

Default cache control max age to use with send_static_file() (the default static file handler) and send_file() , as datetime.timedelta or as seconds.默认缓存控制 max age 与send_static_file() (默认静态文件处理程序)和send_file() ,作为datetime.timedelta或作为秒。 Override this value on a per-file basis using the get_send_file_max_age() hook on Flask or Blueprint, respectively.分别使用 Flask 或 Blueprint 上的get_send_file_max_age()挂钩在每个文件的基础上覆盖此值。 Defaults to 43200 (12 hours).默认为 43200(12 小时)。

Solving this can be as simple as updating the app.config dictionary, like so:解决这个问题就像更新app.config字典一样简单,如下所示:

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

If you do that, your browser will not cache static assets that are served by Flask.如果这样做,您的浏览器将不会缓存 Flask 提供的静态资产。

Use:用:

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

You can update using F5 or CTRL + R .您可以使用F5CTRL + R进行更新。

使用 CTRL+ f5 刷新浏览器

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

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