最近做接口測試的時候,有接口需求爲上傳圖片,一直報錯,錯誤如下:
下面的資料爲網上找的資料,補充了一下爲何會出錯的原因
一、編譯環境
- python 3.7.7
- requests 庫
- PS:文件包括文件,圖片等
二、單個文件(單/多字段對應單/多文件)
在requests中發送文件的接口只有一種,那就是使用requests.post的files參數, 請求形式如下:
url = "http://xxxx.org/post"
data = None
files = { ... }
res = requests.post(url, data, files=files)
而這個files參數是可以接受很多種形式的數據,最基本的2種形式爲:
- 字典類型
- 元組列表類型
1.字典類型
官方推薦使用的字典參數格式如下:
{
"field1" : ("filename1", open("filePath1", "rb")),
"field2" : ("filename2", open("filePath2", "rb"), "image/jpeg"),
"field3" : ("filename3", open("filePath3", "rb"), "image/jpeg", {"header-param" : "xxx"})
}
("filename3", open("filePath3", "rb"), "image/jpeg", {"header-param" : "xxx"})
元組內最多4個元素按順序意義爲(順序固定):
元素1:文件名
元素2:open("filePath3", "rb"):open爲python內置的文件函數,filePath3是文件路徑(包括文件名),rb代表權限
元素3:content_type
元素4:headers
缺省的話則會使用默認值。除了上面的使用形式,其實requests還是支持一個更簡潔的參數形式,如下
{
"field1" : open("filePath1", "rb"),
"field2" : open("filePath2", "rb"),
"field3" : open("filePath3", "rb")
}
request庫中會默認截取filePath的最後一個路徑作爲fileName
2.元組列表類型
其實元組列表的形式與字典的形式基本一樣,除了最外層的包裝不一樣;而在requests內部最終會把字典參數形式 轉換 爲 元組列的形式。官網推薦的用法如下:
[
("field1" : ("filename1", open("filePath1", "rb"))),
["field2" : ("filename2", open("filePath2", "rb"), "image/jpeg")],
("field3" : ("filename3", open("filePath3", "rb"), "image/jpeg", {"header-param" : "xxx"}))
]
三、單字段發送多個文件
1.字典參數形式(有特殊情況,請看下面解釋)
{
"field1" : [
("filename1", open("filePath1", "rb")),
("filename2", open("filePath2", "rb"), "image/png"),
open("filePath3", "rb"),
open("filePath4", "rb").read()
]
}
此形式在3.7.7內會報錯,建議使用元組列表形式
2.元組列表形式
[
("field1" , ("filename1", open("filePath1", "rb"))),
("field1" , ("filename2", open("filePath2", "rb"), "image/png")),
("field1" , open("filePath3", "rb"))
]
!!字典參數形式錯誤原因!!
這裏就是問題所在,因爲最後會把字典轉換爲列表
所以如果結構爲字典的情況下
{
"field1" : [
("filename1", open("filePath1", "rb")),
("filename2", open("filePath2", "rb"), "image/png"),
open("filePath3", "rb"),
open("filePath4", "rb").read()
]
}
會被轉換成
[
("field1", [
("filename1", open("filePath1", "rb")),
("filename2", open("filePath2", "rb"), "image/png"),
open("filePath3", "rb"),
open("filePath4", "rb").read()
])
]
這樣一個列表,列表只有一個元素,元素爲元組,但是判斷的時候上面說了,元組的4個順序是固定意義的,所以看下圖
不知道3.7.7以前的版本是啥樣的,所以最起碼3.7.7不建議使用字典類型的參數去單個字段上傳多個文件