urllib.Request删除Content-Type标头

时间:2017-06-04 09:28:14

标签: python python-3.x http post

我想从POST请求中删除内容类型标头。我已尝试将标头设置为''

try:
    from urllib.request import Request, urlopen
except ImportError:
    from urllib2 import Request, urlopen

url = 'https://httpbin.org/post'
test_data = 'test'

req = Request(url, test_data.encode(), headers={'Content-Type': ''})
req.get_method = lambda: 'POST'
print(urlopen(req).read().decode())

但是这发送:

{
  // ...
  "headers": {
     "Content-Type": "", // ...
  }
  // ...
}

我希望它完全不发送Content-Type,而不是空白。默认情况下,它是application/x-www-form-urlencoded

使用requests

可以轻松实现这一目标
print(requests.post(url, test_data).text)

但这是我需要分发的脚本,所以不能有依赖。我需要它根本没有Content-Type,因为服务器非常挑剔,所以我不能使用text/plainapplication/octet-stream

2 个答案:

答案 0 :(得分:2)

您可以指定自定义处理程序:

try:
    from urllib.request import Request, urlopen, build_opener, BaseHandler
except ImportError:
    from urllib2 import Request, urlopen, build_opener, BaseHandler

url = 'https://httpbin.org/post'
test_data = 'test'

class ContentTypeRemover(BaseHandler):
    def http_request(self, req):
        if req.has_header('Content-type'):
            req.remove_header('Content-type')
        return req
    https_request = http_request

opener = build_opener(ContentTypeRemover())
req = Request(url, test_data.encode())
print(opener.open(req).read().decode())

另一种(hacky)方式:猴子修补请求对象以假装已经存在Content-type标头;阻止AbstractHTTPHandler默认使用Content-Type标头。

req = Request(url, test_data.encode())
req.has_header = lambda header_name: (header_name == 'Content-type' or
                                      Request.has_header(req, header_name))
print(urlopen(req).read().decode())

答案 1 :(得分:0)

只需在@falsetru的答案上方添加

如果您需要过滤的标头更多,req.headers不是您想要的东西,它更像是这样:

class ContentTypeRemover(BaseHandler):
    def __init__(self, headers_to_filter={'Content-type'}): # set or dict works
        self.headers_to_filter = headers_to_filter

    def http_request(self, req):
        for header, value in req.header_items():
            if header in self.headers_to_filter:
                req.remove_header(header)
        return req
    https_request = http_request

如果您需要修改标题,请不要删除它。它有点奇怪(至少这是我发现的唯一可行的方法):

req.remove_header(header)
req.add_header(header, self.modify_headers[header.lower()])