通常提交普通表單時,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。