簡體   English   中英

在 Flask 中使用 HTTP 307 臨時重定向將文件上傳到第三方 API

[英]File upload to third party API with HTTP 307 Temporary Redirect in Flask

我有一個場景,我必須將文件從 Flask 應用程序上傳到第三方 API。 我已將所有 API 請求包裝在 Flask 中以控制 API 的使用。 為此,我將流量從主路由重定向到具有 http 307 狀態的 api 包裝器路由以保留請求正文,並且在 API 包裝器中我使用請求發布到第三方 API 端點。

問題是只有小於 100KB 的文件通過重定向請求發送,大於 100KB 的文件在發送階段以某種方式終止。

307 重定向和負載大小是否有限制?

我嘗試通過觀察網絡計時堆棧跟蹤進行調試,從那里看來請求在發送階段被丟棄了。

主要藍圖

@main.route('/upload/',methods=['POST','GET'])  
def upload(): 
    #for ajax call
    if request.method == 'POST'
        return redirect(url_for('api.file_push'),code=307)
    else:
        return render_template('file-upload.html')

API藍圖

@api.route('/upload/',methods=['POST'])
def file_push():
    upload_file = request.files['file']
    filename = urllib.parse.quote(upload_file.filename)
    toUpload = upload_file.read()
    result=requests.post(apiInterfaces.FILE_UPLOAD_INTERFACE+'/'+filename,files{'file':toUpload})
    return result

是的,我可以直接從主路由向 API 端點發送發布請求,但我不想這樣做,這會破壞我的系統設計和架構。

我假設您正在使用 Python,並且可能會requests ,所以這個答案將基於我在解決這個問題時學到的知識(與同事一起調試)。 我用psf/requests提交了錯誤報告 這里有一個相關的答案證實了我的懷疑。

似乎當您使用requests (和urllib3 )發起PUT請求時,整個請求在查看來自服務器的響應之前發送,但一些服務器可以在此期間發送HTTP 307 發生以下兩種情況之一:

  1. 服務器通過發送響應關閉連接,即使客戶端尚未完成發送整個文件。 在這種情況下,客戶端可能會看到一個已關閉的連接,並且您不會得到可用於重定向的響應(這種情況發生在urllib3>1.26.10 (大致))但requests沒有正確處理這種情況
  2. 服務器發送響應,您將文件重新上傳到第二個位置( urllib3==1.26.3在使用requests時有此行為)。 從技術上講, urllib3中有一個錯誤,它應該失敗,但默默地讓你上傳......

但是,似乎如果您期望重定向,最明顯的解決方案可能是先通過PUT發送一個空字節,為新 URL 返回一個有效響應 [不要遵循重定向],然后使用該響應來執行完整文件的PUT 有了請求,它可能是這樣的

>>> import requests
>>> from io import BytesIO
>>> data = BytesIO(b'\x00')
>>> response = request.put(url, data=data, allow_redirects=False)
>>> request.put(response.headers['Location'], data=fp, allow_redirects=False)

到那時,你會沒事的(假設你只希望這里有一個重定向)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM