Dev*_*ain 3 python python-3.x python-requests
当我尝试使用 python requests 库将文件发布到服务器时,我收到 http 代码 400(错误请求)。
curl成功对应的请求:
curl -X POST -i https://de.api.labs.sophos.com/analysis/file/static/v1 \
-H 'Authorization: auth_string' \
-H 'Content-Type: multipart/form-data' \
-F "file=@filename"
Run Code Online (Sandbox Code Playgroud)
API 文档: https: //api.labs.sophos.com/doc/analysis/file/static.html
有人可以帮我解决我可能做错了什么吗?
到目前为止我的代码:
import requests
url = "https://de.api.labs.sophos.com/analysis/file/static/v1"
headers = {'content-type': 'multipart/form-data', 'Authorization': authorization}
with open(filepath, 'rb') as f:
files = {'file': f} # Even tried {'file': f.read()}
r = requests.post(url, files=files, headers=headers)
if r.status_code in [200, 202]:
return r.json()
else:
return r
Run Code Online (Sandbox Code Playgroud)
尝试这样做:
import requests
url = "https://de.api.labs.sophos.com/analysis/file/static/v1"
headers = {'Authorization': authorization} # no Content-Type here
r = requests.post(url, headers=headers, files={"file": open(filepath, "rb")})
print(r.status_code, r.text)
Run Code Online (Sandbox Code Playgroud)
发布文件时不应Content-Type手动设置标题。requests
原因有两个:
requests将在发出实际的 HTTP 请求之前隐式设置Content-Type为(例如)multipart/form-dataContent-LengthContent-Type: multipart/form-data应该指定边界。如果没有设置边界,服务器将无法正确从请求体中读取数据。因此,如果您使用.Content-Typemultipart/form-data在您的示例中,您尚未为请求设置边界。事实是,如果您覆盖标头(您确实这样做了),requests 则不会为您设置它。Content-Type然后服务器无法读取请求正文中的文件。因此,它会返回给你400 Bad Request。
print(r.request.headers["Content-Type"])您可以在提出请求后通过输入进行检查。它将输出这个:
multipart/form-data
Run Code Online (Sandbox Code Playgroud)
,但它必须看起来像这样:
multipart/form-data; boundary=6387a52fb4d1465310a2b63b2d1c6e70
Run Code Online (Sandbox Code Playgroud)
另一方面,curl 隐式添加边界,因此您一切都很好并且您收到了200 OK。
您也可以检查一下:
curl -H 'Content-Type: multipart/form-data' -F "file=@123.txt" -v http://httpbin.org/post
Run Code Online (Sandbox Code Playgroud)
哪个输出:
* Connected to httpbin.org (34.230.136.58) port 80 (#0)
> POST /post HTTP/1.1
> Host: httpbin.org
> User-Agent: curl/7.47.0
> Content-Type: multipart/form-data; boundary=------------------------d257f5f4377a3997
...
Run Code Online (Sandbox Code Playgroud)