1. 程式人生 > 實用技巧 >Flask 下載時資料流的返回

Flask 下載時資料流的返回

Flask 下載時資料流的返回


關於flask 的下載功能實現,網上有一大堆,大致上是這樣(適用於預下載的檔案就在你的伺服器裡)

from flask import jsonify, json, request, make_response, Response, stream_with_context, send_file
import mimetypes

@api.route("/downloadFile/<path:filename>")
def downloadFile(filename):
    import os
    baseDir = os.path.join(os.getcwd(), "
static") pathname = os.path.join(baseDir, filename) print pathname def send_chunk(): # 流式讀取 store_path = pathname with open(store_path, 'rb') as target_file: while True: chunk = target_file.read(20 * 1024 * 1024) # 每次讀取20M if not chunk:
break yield chunk return Response(send_chunk(), content_type='application/octet-stream') @api.route("/downloadFile2/<path:filename>") def downloadFile2(filename): import os baseDir = os.path.join(os.getcwd(), "static") pathname = os.path.join(baseDir, filename) f
= open(pathname, "rb") response = Response(f.readlines()) # response = make_response(f.read()) mime_type = mimetypes.guess_type(filename)[0] response.headers['Content-Type'] = mime_type response.headers['Content-Disposition'] = 'attachment; filename={}'.format(filename.encode().decode('latin-1')) return response

但是我遇到的情況是下載的檔案不在本地伺服器,所以按上面的邏輯的話,我需要自己先下載好了才能傳輸給使用者,可以說有點蠢

所以經過研究,發現了一種解決辦法(跳過自己下載好了再傳輸的尷尬,直接將請求到的資料返回給使用者)

from werkzeug._compat import wsgi_encoding_dance

@app.route("/downloadFile/<hash_str>") def download_file(hash_str): song = get_download_link(hash_str) # 首先定義一個生成器,每次讀取512個位元組 def generate(): if song['url']: r = requests.get(song['url'], cookies=request.cookies, stream=True) for chunk in r.iter_content(chunk_size=512): if chunk: yield chunk response = Response(stream_with_context(generate())) name = wsgi_encoding_dance(FileName) # .encode("utf-8").decode("latin1") content_disposition = "attachment; filename={}".format(name) response.headers['Content-Disposition'] = content_disposition return response