从 CDN 而不是生产中的 Flask 提供静态文件 [英] Serve static files from a CDN rather than Flask in production

查看:26
本文介绍了从 CDN 而不是生产中的 Flask 提供静态文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 Flask 应用程序中,我通过开发环境中的应用程序提供静态资产,但我想在生产中使用 CDN.每个资产都加载在一个名为 base.html 的模板中,所以我想最简单的解决方案是将变量传递给渲染函数并在模板中使用它,例如:

In my Flask app I serve the static assets through the app in the dev env, but I'd like to use a CDN in production. Every asset is loaded in a template called base.html, so I guess the easiest solution is to pass a variable to the render function and use it in the template like:

<script src="{{ STATIC_URL }}/js/main.js"></script>

通常在 dev env 中它是一个空字符串,而在生产中它是 cdn url.我想避免将此 STATIC_URL 变量传递给每个视图.我可以让它工作

Normally it would be an empty string in the dev env, and the cdn url in production. I'd like to avoid passing this STATIC_URL variable to every view. I could make it work with

@bp.context_processor
def set_static_path():
    return dict(STATIC_URL='https://foo.bar.com')

但对我来说这似乎有点hacky.有没有更好的方法来解决这个问题?

But for me this seems a little hacky. Is there a better way to solve this problem?

推荐答案

无需更改链接到静态文件的方式,您仍然可以使用 url_for('static', filename='myfile.txt').如果配置了 CDN,则将默认静态视图替换为重定向到 CDN 的视图.

There's no need to change how you link to static files, you can still use url_for('static', filename='myfile.txt'). Replace the default static view with one that redirects to the CDN if it is configured.

from urllib.parse import urljoin
# or for python 2: from urlparse import urljoin
from flask import redirect

@app.endpoint('static')
def static(filename):
    static_url = app.config.get('STATIC_URL')

    if static_url:
        return redirect(urljoin(static_url, filename))

    return app.send_static_file(filename)

无论您是在开发机器上还是生产机器上,将 STATIC_URL 配置值设置为 CDN,对静态文件的请求将被重定向到那里.

Whether you're on a dev machine or production, set the STATIC_URL config value to the CDN and requests for static files will be redirected there.

重定向相对便宜,并且被浏览器记住.如果您发现性能受到它们的显着影响,您可以编写一个在使用 CDN 时直接链接的函数.

Redirects are relatively cheap, and are remembered by browsers. If you get to the point where performance is meaningfully affected by them, you can write a function that links directly when using the CDN.

@app.template_global()
def static_url(filename):
    static_url = app.config.get('STATIC_URL')

    if static_url:
        return urljoin(static_url, filename)

    return url_for('static', filename=filename)

template_global 装饰器使该函数在所有模板中都可用.当您需要静态文件的 url 时,使用它代替 url_for.

The template_global decorator makes the function available in all templates. Use it instead of url_for when you need urls for static files.

可能已经有一个 Flask 扩展可以为您执行此操作.例如,Flask-S3 提供了一个 url_for提供来自 AWS S3 的静态文件.

There may be a Flask extension that does this for you already. For example, Flask-S3 provides a url_for that serves static files from AWS S3.

这篇关于从 CDN 而不是生产中的 Flask 提供静态文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆