Not possible to set content-type to application/json using urllib2

[亡魂溺海] 提交于 2019-12-08 16:03:03

问题


This little baby:

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'}))

Produces the following request (as seen with 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"} 

I do not want that Content-Type: application/x-www-form-urlencoded. I am explicitely saying that I want ('Content-Type', 'application/json')

What's going on here?!


回答1:


If you want to set custom headers you should use a Request object:

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)



回答2:


I got hit by the same stuff and came up with this little gem:

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'}))

You just add a handler for HTTP requests that replaces the header that OpenerDirector previously added.




回答3:


Python version:Python 2.7.15 I found that in urllib2.py:1145:

        for name, value in self.parent.addheaders:
            name = name.capitalize()
            if not request.has_header(name):
                request.add_unredirected_header(name, value)

...
    def has_header(self, header_name):
        return (header_name in self.headers or
                header_name in self.unredirected_hdrs)

Otherwise,application/x-www-form-urlencoded has been in unredirected_hdrs and it won't be overwrite

You can solve like


import urllib.request
from http.cookiejar import CookieJar

import json

url = 'http://www.baidu.com'
req_dict = {'k': 'v'}

cj = CookieJar()
handler = urllib.request.HTTPCookieProcessor(cj)
opener = urllib.request.build_opener(handler)

req_json = json.dumps(req_dict)
req_post = req_json.encode('utf-8')
headers = {}
#headers['Content-Type'] = 'application/json'
req = urllib.request.Request(url=url, data=req_post, headers=headers)

#urllib.request.install_opener(opener)
#res = urllib.request.urlopen(req)
# or
res = opener.open(req)

res = res.read().decode('utf-8')



回答4:


The problem is the capitalization of the Header name. You should use Content-type and not Content-Type.



来源:https://stackoverflow.com/questions/13920211/not-possible-to-set-content-type-to-application-json-using-urllib2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!