首页  >  问答  >  正文

如何在 Flask 中提供静态文件

<p>所以这很尴尬。我在 <code>Flask</code> 中组装了一个应用程序,目前它仅提供一个静态 HTML 页面,其中包含一些指向 CSS 和 JS 的链接。我在文档 <code>Flask</code> 中找不到描述返回静态文件的位置。是的,我可以使用 <code>render_template</code> 但我知道数据没有模板化。我认为 <code>send_file</code> 或 <code>url_for</code> 是正确的,但我无法让它们工作。与此同时,我打开文件,读取内容,并使用适当的 mimetype 来设置 <code>Response</code>:</p> <pre class="brush:php;toolbar:false;">import os.path from flask import Flask, Response app = Flask(__name__) app.config.from_object(__name__) def root_dir(): # pragma: no cover return os.path.abspath(os.path.dirname(__file__)) def get_file(filename): # pragma: no cover try: src = os.path.join(root_dir(), filename) # Figure out how flask returns static files # Tried: # - render_template # - send_file # This should not be so non-obvious return open(src).read() except IOError as exc: return str(exc) @app.route('/', methods=['GET']) def metrics(): # pragma: no cover content = get_file('jenkins_analytics.html') return Response(content, mimetype="text/html") @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def get_resource(path): # pragma: no cover mimetypes = { ".css": "text/css", ".html": "text/html", ".js": "application/javascript", } complete_path = os.path.join(root_dir(), path) ext = os.path.splitext(path)[1] mimetype = mimetypes.get(ext, "text/html") content = get_file(complete_path) return Response(content, mimetype=mimetype) if __name__ == '__main__': # pragma: no cover app.run(port=80)</pre> <p>有人想为此提供代码示例或网址吗?我知道这会非常简单。</p>
P粉754473468P粉754473468423 天前519

全部回复(2)我来回复

  • P粉155551728

    P粉1555517282023-08-24 12:55:28

    如果您只想移动静态文件的位置,那么最简单的方法是在构造函数中声明路径。在下面的示例中,我已将模板和静态文件移动到名为 web 的子文件夹中。

    app = Flask(__name__,
                static_url_path='', 
                static_folder='web/static',
                template_folder='web/templates')
    • static_url_path='' 从 URL 中删除所有前面的路径。
    • static_folder='web/static' 提供在文件夹中找到的任何文件 web/static 作为静态文件。
    • template_folder='web/templates' 类似地,这会更改 模板文件夹。

    使用此方法,以下 URL 将返回 CSS 文件:

    <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">

    最后,这是文件夹结构的快照,其中 flask_server.py 是 Fl​​ask 实例:

    回复
    0
  • P粉212971745

    P粉2129717452023-08-24 09:31:38

    在生产中,在应用程序前面配置 HTTP 服务器(Nginx、Apache 等),以处理来自静态文件夹的 /static 请求。专用 Web 服务器非常擅长高效地提供静态文件,尽管在低容量时您可能不会注意到与 Flask 相比的差异。

    Flask 会自动创建一个 /static/ 路由,该路由将为 Python 旁边的 static 文件夹下的任何 filename 提供服务定义 Flask 应用程序的模块。使用url_for链接到静态文件:url_for('static', filename='js/analytics.js')

    您还可以使用 send_from_directory 来提供文件从您自己的路线中的目录中。这需要一个基本目录和一个路径,并确保该路径包含在该目录中,这样可以安全地接受用户提供的路径。如果您想在提供文件之前检查某些内容,例如登录用户是否具有权限,这可能很有用。

    from flask import send_from_directory
    
    @app.route('/reports/<path:path>')
    def send_report(path):
        return send_from_directory('reports', path)

    请勿send_filesend_static_file 与用户提供的路径一起使用。这将使您面临目录遍历攻击send_from_directory 旨在安全地处理已知目录下用户提供的路径,如果路径尝试转义该目录,则会引发错误。

    如果您在内存中生成文件而不将其写入文件系统,则可以将 BytesIO 对象传递给 send_file 将其作为文件提供。在这种情况下,您需要将其他参数传递给 send_file,因为它无法推断文件名或内容类型等内容。

    回复
    0
  • 取消回复