问题 无法使用urllib2将content-type设置为application / json


这个小宝贝:

import urllib2
import simplejson as json

opener = urllib2.build_opener()
opener.addheaders.append(('Content-Type', 'application/json'))
response = opener.open('http://localhost:8000',json.dumps({'a': 'b'}))

产生以下请求(如ngrep所示):

sudo ngrep -q -d lo '^POST .* localhost:8000'

T 127.0.0.1:51668 -> 127.0.0.1:8000 [AP]
  POST / HTTP/1.1..Accept-Encoding: identity..Content-Length: 10..Host: localhost:8000..Content-Type: application/x-www-form-urlencoded..Connection: close..User-Agent:
   Python-urllib/2.7....{"a": "b"} 

我不要那个 Content-Type: application/x-www-form-urlencoded。我明确地说我想要 ('Content-Type', 'application/json')

这里发生了什么?!


8678
2017-12-17 18:48


起源



答案:


如果要设置自定义标头,则应使用a Request 目的:

import urllib2
import simplejson as json

opener = urllib2.build_opener()
req = urllib2.Request('http://localhost:8000', data=json.dumps({'a': 'b'}),
      headers={'Content-Type': 'application/json'})
response = opener.open(req)

15
2017-12-17 19:03



谢谢,但这并没有解决我的问题。代码已经实现(遗留),我只需要更改 Content-Type。为什么 opener.addheaders.append 不按预期工作? - dangonfast
标题在 addheaders 只有在没有添加相应标题的情况下才会添加,但是如果使用的是 data 参数内容类型已隐式设置为默认值(x-www-form-urlencoded)。在这种情况下,这优先于标题 addheaders。 - mata
这种行为有点出乎意料。无论如何,多亏了你的建议,我已经能够让它运作起来。谢谢! - dangonfast


答案:


如果要设置自定义标头,则应使用a Request 目的:

import urllib2
import simplejson as json

opener = urllib2.build_opener()
req = urllib2.Request('http://localhost:8000', data=json.dumps({'a': 'b'}),
      headers={'Content-Type': 'application/json'})
response = opener.open(req)

15
2017-12-17 19:03



谢谢,但这并没有解决我的问题。代码已经实现(遗留),我只需要更改 Content-Type。为什么 opener.addheaders.append 不按预期工作? - dangonfast
标题在 addheaders 只有在没有添加相应标题的情况下才会添加,但是如果使用的是 data 参数内容类型已隐式设置为默认值(x-www-form-urlencoded)。在这种情况下,这优先于标题 addheaders。 - mata
这种行为有点出乎意料。无论如何,多亏了你的建议,我已经能够让它运作起来。谢谢! - dangonfast


我被同样的东西击中并想出了这个小宝石:

import urllib2
import simplejson as json

class ChangeTypeProcessor(BaseHandler):
    def http_request(self, req):
        req.unredirected_hdrs["Content-type"] = "application/json"
        return req

opener = urllib2.build_opener()
self.opener.add_handler(ChangeTypeProcessor())
response = opener.open('http://localhost:8000',json.dumps({'a': 'b'}))

您只需为替换标头的HTTP请求添加处理程序 OpenerDirector 之前补充说。


0
2017-08-31 11:55