描述:git
一、以前在寫項目mock代碼時,碰到一個上傳文件的接口,但項目接口自己有token保護機制,碰到token失效時,須要從新獲取一次token後,再次對上傳文件發起請求,在實際調用中發現,第一次調用上傳接口能正常返回,但第二次獲取新token再調用上傳文件接口時,一直無返回數據,直到超時報錯github
有問題的代碼以下:post
1 from requests_toolbelt import MultipartEncoder 2 import requests 3 4 m = MultipartEncoder(fields={'upload': open('test.txt', 'rb')}, 5 boundary='----WebKitFormBoundarytZTJQrWcjjcJIMVQ') 6 params = {'path': 'test.txt', 7 'token': '123456', 8 'num': 0, 'offset': 0, 9 'limit': 8} 10 response = requests.post('http://httpbin.org/post', 11 params=params, 12 data=m, 13 headers={'Content-Type': m.content_type}) 14 # print("1: ", response.text) 15 # print("2: ", response.request.body) 16 # print("3: ", response.request.headers) 17 18 print(2) 19 response1 = requests.post('http://httpbin.org/post', 20 params=params, 21 data=m, 22 headers={'Content-Type': m.content_type})
二、後面經過fiddler抓包發現,在第二次請求上傳接口時,body丟失了,經過debug定位,發現第二次請求在調用requests庫時,body中是有值的,當進入requests庫後,body丟失,故在requests官方庫中提問,最終找到了解決辦法spa
fiddler抓包截圖以下:debug
第一次請求:3d
第二次請求:code
三、最終request庫的參與者回覆了個人疑問,提示我須要在第一次讀取文件後,把光標挪到首位,或關閉文件,在第二次調用時,再次從文件首位開始讀取orm
四、修改後的代碼:token
1 from requests_toolbelt import MultipartEncoder 2 import requests 3 4 def read_file(filepath='test.txt'): 5 fp = open(filepath, 'rb') 6 # 這裏要把光標挪到首位,或者直接fp.close()關閉文件 7 fp.seek(0) 8 return fp 9 print(read_file()) 10 m = MultipartEncoder(fields={'upload':read_file()}, 11 boundary='----WebKitFormBoundarytZTJQrWcjjcJIMVQ') 12 params = {'path': 'test.txt', 13 'token': '123456', 14 'num': 0, 'offset': 0, 15 'limit': 8} 16 response = requests.post('http://httpbin.org/post', 17 params=params, 18 data=m, 19 headers={'Content-Type': m.content_type}) 20 print("1: ", response.text) 21 22 # 這裏從新組裝,並調用一下獲取文件方法 23 m1 = MultipartEncoder(fields={'upload': read_file()}, 24 boundary='----WebKitFormBoundarytZTJQrWcjjcJIMVQ') 25 params1 = {'path': 'test.txt', 26 'token': '123456', 27 'num': 0, 'offset': 0, 28 'limit': 8} 29 response1 = requests.post('http://httpbin.org/post', 30 params=params1, 31 data=m1, 32 headers={'Content-Type': m1.content_type}) 33 print("2: ", response1.text)
在此備註下,以防之後再次踩坑!!!