python requests 上傳檔案_python3使用requests上傳檔案,content-type踩的坑
通常提交普通表單時,requests的post方法可以指定headers,所以我在使用requests模擬上傳檔案行為時,直接按照下面的方式寫了:
然後伺服器就報出了找不到分隔符Invalid multipart/form-data: multipart boundary not found
網上找了半天也沒找到為什麼,倒是大家給的示例比我寫的少用了一個headers,嘗試著調整了一下,去掉headers引數就可以上傳了,我懷疑時requests內部會檢查使用者是否已經定義了headers,如果定義了,則直接使用,否則requests根據其他引數自動給生成headers。
所以我想,如果是這樣,那我再headers裡把需要的內容都寫上,應該也是可以的,上面提示未找到boundary,那麼我自己寫上boundary(http協議允許使用者自定義boundary):
定義了boundary,但是伺服器卻報出沒有final boundary,我們知道,post編碼時,傳送前會用boundary分割不同欄位,最後以前後都有--的boundary結束。所以,出現找不到final boundary應該就是自定義的boundary沒有起到作用,去看原始碼吧。
翻出requests原始碼,在models.py檔案裡,函式就是對post欄位進行編碼的,對於上傳檔案來講,content_type來自函式;最終通過生成boundary,拼接出模組內的content_type。
如果使用者沒有自定義content-type,那麼就使用模組內自己隨機生成的boundary。但是返回到prepare_body裡,最後會判斷使用者是否定義了Content-type,如果定義了則使用使用者定義好的,相關程式碼如下:
所以,從這裡可以看出,無論使用者怎麼定義Content-type,實際用到的boundary還是模組自己生成的,而且一旦使用者自定義了content-type,最終post請求的headers裡攜帶的boundary跟實際編碼用到的boundary就會不一致,導致伺服器端無法解析。
總結為一句話:使用requests的post方法上傳檔案時,不能自定義headers裡的content-type。