在生产中从CDN而不是Flask提供静态文件

时间:2016-03-06 07:45:55

标签: python flask jinja2

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

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

通常它是dev env中的空字符串,以及生产中的cdn url。我想避免将此STATIC_URL变量传递给每个视图。我可以使用

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

但对我来说,这似乎有点笨拙。有没有更好的方法来解决这个问题?

3 个答案:

答案 0 :(得分:14)

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

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,静态文件请求将重定向到那里。

重定向相对便宜,并且被浏览器记住。如果达到性能受其影响的程度,您可以编写一个在使用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_for

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

答案 1 :(得分:2)

这个烧瓶cdn integration guide可能值得一读。基本上你可以安装Flask-CDN extension并在你的app.py文件中定义你的CDN URL,如下所示:

for([int] $i=0;$i -lt $People.Peoplename.count;$i++)
{
     for([int] $j=$i+1;$j -lt $ People.Peoplename.count;$j++)
     {
        if($People [$i].Peoplename -eq $ People [$j].Peoplename)
        {
             write-host "Duplicate item found" $People [$i].Peoplename
        }

    }
} 

答案 2 :(得分:0)

我使用Flask Assets和Flask-CDN遇到了类似的问题。我发现Flask-CDN正在尝试并且无法为每个资产生成时间戳。失败后,它将恢复为相对URL。

添加app.config['CDN_TIMESTAMP'] = False解决了该问题。