【问题标题】:python requests drops "data" when use of "header" in requestpython请求在请求中使用“标头”时丢弃“数据”
【发布时间】:2018-10-04 09:22:47
【问题描述】:

当我想上传文件时,我正在处理需要此请求类型的站点的 REST API:

  1. 标题中的“授权”和多部分内容类型
  2. 文件格式为二进制字符串(正文)
  3. 请求 URL 中的文件类型

所以我做了这段代码:

import requests

url = 'http://httpbin.org/post'

parameters = {
        'format': 'pdf',
        }

headers = {
  'Content-Type': 'multipart/form-data',
  'Accept': 'application/json',
  'Authorization' : 'Some authorization code'
        }

data = {'file': open('1.pdf', 'rb')}

r = requests.post(url, params=parameters, headers=headers, data=data)

print(r.text)

但似乎请求正在删除数据:

{
  "args": {
    "format": "pdf"
  },
  "data": "",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "application/json",
    "Accept-Encoding": "gzip, deflate",
    "Authorization": "Some authorization code",
    "Connection": "close",
    "Content-Length": "30",
    "Content-Type": "multipart/form-data",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.18.1"
  },
  "json": null,
  "origin": "x.x.x.x",
  "url": "http://httpbin.org/post?format=pdf"
}

当我删除请求中的“标头”部分时它可以工作:

r = requests.post(url, params=parameters, data=data)

因为响应是:

{
  "args": {
    "format": "pdf"
  },
  "data": "",
  "files": {},
  "form": {
    "fax_file": "some samplae texts\n"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Connection": "close",
    "Content-Length": "30",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.18.1"
  },
  "json": null,
  "origin": "x.x.x.x",
  "url": "http://httpbin.org/post?format=pdf"
}

我也尝试过准备好的请求,结果是一样的。

【问题讨论】:

  • 如果您在data 中通过读取文件而不是文件对象传递字节会发生什么?
  • @match 仍然下降,直到我从标题中删除 'content-type'

标签: python rest post python-requests


【解决方案1】:

您正在尝试发布文件数据,因此请使用files 选项:

r = requests.post(url, params=parameters, files=data, headers=headers)

但是,您真的不应该设置 Content-Type 标头;它是在您使用 files 选项时为您设置的。在这种情况下,标头包含字段边界,以真正希望库为您处理此问题:

headers = {
  'Accept': 'application/json',
  'Authorization' : 'Some authorization code'
}

如果您保留 Content-Type 标头,则必须预先生成内容主体,以便能够向接收服务器提供所需的边界信息。

您也可以尝试删除 Accept 标头;默认情况下,requests 将添加 Accept: */*,如果您不指定该标头,则表明 anything 是可以接受的。

仅使用data参数时,参数编码为application/x-www-form-urlencoded形式,不支持大文件数据,并且您的Content-Type标头与实际的POST正文内容不匹配。

请参阅 requests 文档中的 Post a Multipart-Encoded File 和 Stack Overflow 上的 application/x-www-form-urlencoded or multipart/form-data?

演示:

>>> import requests
>>> url = 'http://httpbin.org/post'
>>> parameters = {'format': 'pdf'}
>>> headers = {
...   'Accept': 'application/json',
...   'Authorization' : 'Some authorization code',
... }
>>> data = {'file': open('1.pdf', 'rb')}
>>> r = requests.post(url, params=parameters, files=data, headers=headers)
>>> print(r.text)
{
  "args": {
    "format": "pdf"
  },
  "data": "",
  "files": {
    "file": "<file data as base64>"
  },
  "form": {},
  "headers": {
    "Accept": "application/json",
    "Accept-Encoding": "gzip, deflate",
    "Authorization": "Some authorization code",
    "Cache-Control": "max-age=0",
    "Connection": "close",
    "Content-Length": "374751",
    "Content-Type": "multipart/form-data; boundary=d4b84f8bfd464e3f97e3de584d7315fc",
    "Host": "httpbin.org",
    "O2Gw-Id": "03",
    "User-Agent": "python-requests/2.18.4",
    "X-Gateway": "wap.london.02.net"
  },
  "json": null,
  "origin": "10.120.6.78, 82.132.221.209",
  "url": "http://httpbin.org/post?format=pdf"
}

注意 Content-Type 标头的 multipart/form-data; boundary=d4b84f8bfd464e3f97e3de584d7315fc 值!

【讨论】:

    猜你喜欢
    • 2019-04-10
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    相关资源
    最近更新 更多