首頁  >  問答  >  主體

如何在 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 天前515

全部回覆(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
  • 取消回覆