【问题标题】:Serve static files from a CDN rather than Flask in production在生产环境中从 CDN 而不是 Flask 提供静态文件
【发布时间】:2016-03-06 07:45:55
【问题描述】:

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

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

通常在开发环境中它是一个空字符串,而在生产环境中它是 cdn url。我想避免将这个 STATIC_URL 变量传递给每个视图。我可以让它工作

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

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

【问题讨论】:

    标签: python flask jinja2


    【解决方案1】:

    无需更改链接到静态文件的方式,您仍然可以使用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 时,请使用它而不是 url_for


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

    【讨论】:

      【解决方案2】:

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

      from flask import Flask
      from flask.ext.cdn import CDN
      
      app = Flask(__name__)
      app.config['CDN_DOMAIN'] = 'cdn.yourdomain.com'
      CDN(app)
      

      【讨论】:

        【解决方案3】:

        我在使用 Flask Assets 和 Flask-CDN 时遇到了类似的问题。我发现 Flask-CDN 正在尝试为每个资产生成时间戳,但未能成功。如果失败,它将恢复为相对 URL。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-09-25
          • 2014-06-06
          • 2019-12-12
          • 1970-01-01
          • 1970-01-01
          • 2012-12-08
          • 2017-12-30
          相关资源
          最近更新 更多