上傳文件接口調試


最近在寫腳本時有一個功能是上傳附件,也趁這個機會學習了下對於上傳文件類的接口該如何進行傳參

本次介紹2種方式來上傳附件:一種是通過jmeter;另一種是通過python的requests庫

接口參數分析

在講具體方法之前,先來分析下這次上傳附件接口的headers與攜帶的參數信息

headers種主要看content-type,這個請求中的content-type如下

content-type: multipart/form-data; boundary=----WebKitFormBoundaryKtD3qxHwCR9S9Wdy
 
 
 查了一些資料,大概意思是說:數據以 multipart/form-data編碼, boundary 用於分割不同的字段
繼續看下參數是如何的,可能就理解上面說的boundary用於分割字段是什么意思了,chrome控制台下顯示的參數信息如下
 
------WebKitFormBoundaryKtD3qxHwCR9S9Wdy
Content-Disposition: form-data; name="type"
 
3
------WebKitFormBoundaryKtD3qxHwCR9S9Wdy
Content-Disposition: form-data; name="file"; filename="test.jpg"
Content-Type: image/jpeg
 
 
------WebKitFormBoundaryKtD3qxHwCR9S9Wdy--


 

 

 

 

 

可以看到消息主體里按照字段個數又分為多個結構類似的部分,每部分都是以 --boundary 開始,緊接着是內容描述信息,然后是回車,最后是字段具體內容(文本或二進制);

如果傳輸的是文件,還要包含文件名和文件類型信息;

消息主體最后以 --boundary-- 標示結束;

另外boundary每次都是隨機生成的!!!

更多內容請看:https://imququ.com/post/four-ways-to-post-data-in-http.html

1. jmeter上傳附件

以我這個請求為例,來說明一下如何填寫請求參數,先把請求body再次放在在這里

------WebKitFormBoundaryKtD3qxHwCR9S9Wdy
Content-Disposition: form-data; name="type"
 
3
------WebKitFormBoundaryKtD3qxHwCR9S9Wdy
Content-Disposition: form-data; name="file"; filename="test.jpg"
Content-Type: image/jpeg
 
 
------WebKitFormBoundaryKtD3qxHwCR9S9Wdy--

 

 

 

 

 

 

如果請求body中除了需要上傳文件外,還需要上傳其他參數,如上面的第一部分,表示有個參數名為"type",它的值為3,需要把它填入jmeter的【參數】中

在【文件上傳】中填寫附件的參數信息

(1) 勾選【對POST使用multipart/form-data】

(2) 文件名稱:附件絕對路徑

(3) 參數名稱:這個根據你在chrome控制台看到參數名稱來填寫,回頭看上面貼出來的請求body

第二部分就是對上傳文件的文件名和文件類型的描述,觀察內容可以發現

name=“file”,所以這里的參數名稱就填寫“file”(填錯的話,一般會報錯的)

Content-Type為image/jpeg,所以jmeter中的MIME類型就填寫“image/jpeg”

ps.關於headers的一點說明:剛開始的時候,我一直想着在信息頭管理器中加上固定的 content-type: multipart/form-data; boundary=----WebKitFormBoundaryKtD3qxHwCR9S9Wdy

 但是實際運行腳本時總是報錯,查看結果樹中的請求頭,也並不是自己定義的這個boundary,貌似自己生成了一個boundary

  后來把請求頭中的content-type去掉后,再次運行就成功了

 綜上,在jmeter中進行文件上傳的請求腳本就寫好了

2. 使用python的requests庫上傳文件

 在使用requests上傳文件時,可以先看看官方文檔的一段描述:

https://requests.readthedocs.io/zh_CN/latest/user/quickstart.html#post-multipart-encoded

Requests 使得上傳多部分編碼文件變得很簡單:

>>> url = 'http://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')}

>>> r = requests.post(url, files=files)
>>> r.text
{
  ...
  "files": {
    "file": "<censored...binary...data>"
  },
  ...
}

你可以顯式地設置文件名,文件類型和請求頭:

>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}

>>> r = requests.post(url, files=files)
>>> r.text
{
  ...
  "files": {
    "file": "<censored...binary...data>"
  },
  ...
}

通過這個例子,可以知道requests上傳文件是通過files關鍵字來完成的:先定義一個變量files,它是一個字典,key=file,value則是打開的二進制文件;然后發送post請求時,帶上file參數即可

拿我這次的請求來說,如下

files = {"file": ("/data/image/test.jpg", 'rb'))}
payload={
  type: 3 } response
= requests.post(url, files=files, data=payload, headers=headers)

payload中定義的是請求body中的type參數;files是本次要上傳的文件;

發送post請求時,需要用files關鍵字發送文件,用data關鍵字發送payload

執行這段腳本能夠得到和jmeter同樣的結果

接下來查看下發送出的請求攜帶的請求頭是什么樣的

print(response.request.headers)

結果如下

{
    'User-Agent': 'python-requests/2.22.0',
    'Accept-Encoding': 'gzip, deflate',
    'Accept': '*/*',
    'Connection': 'keep-alive','Content-Length': '110824',
    'token': 'sImDk2YzBkOTkzNFwiLFwiZW1haWxcIjpcIjgxZjcwZjJkOWFmODA1MD',
    'Content-Type': 'multipart/form-data; boundary=59a681a11824f2dd578becdd4195cf9b'
}

可以發現,python自己給它補全了Content-Type,並且boundary也是自己生成的一段字符

 至於如何自己定義boundary還得再研究研究


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM