【问题标题】:TypeError: can't concat bytes to str python3TypeError:无法将字节连接到 str python3
【发布时间】:2017-05-10 19:21:05
【问题描述】:

我正在尝试使用urllib3python3 中发送HTTP 请求。

这里是代码sn-p

request_body = {'grant_type':'password','username': username,'password': password}
request_headers = {'Content-Type' : 'application/x-www-form-urlencoded','Authorization': "hash string"}
http = urllib3.PoolManager()
response = http.request('POST', 'https://api/url/endpoint', headers=request_headers, body=request_body)

但是当我尝试执行它时,它会抛出以下错误。

TypeError: can't concat bytes to str

完整的追溯

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/Mubin/anaconda/lib/python3.6/site-
packages/urllib3/request.py", line 70, in request
**urlopen_kw)
File "/Users/Mubin/anaconda/lib/python3.6/site-
packages/urllib3/request.py", line 148, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
File "/Users/Mubin/anaconda/lib/python3.6/site-
  packages/urllib3/poolmanager.py", line 321, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "/Users/Mubin/anaconda/lib/python3.6/site-
  packages/urllib3/connectionpool.py", line 600, in urlopen
chunked=chunked)
File "/Users/Mubin/anaconda/lib/python3.6/site-
  packages/urllib3/connectionpool.py", line 356, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/Users/Mubin/anaconda/lib/python3.6/http/client.py", line 1239, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/Users/Mubin/anaconda/lib/python3.6/http/client.py", line 1285, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/Users/Mubin/anaconda/lib/python3.6/http/client.py", line 1234, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/Users/Mubin/anaconda/lib/python3.6/http/client.py", line 1064, in _send_output
+ b'\r\n'

谁能指出我做错了什么?

编辑

request_body 类型检查

>>> type(request_body)
    <class 'dict'>
>>> type(request_body['username'])
    <class 'str'>
>>> type(request_body['password'])
    <class 'str'>
>>> type(request_body['grant_type'])
    <class 'str'>

【问题讨论】:

  • usernamepassword的类型有哪些?
  • 都是字符串&lt;class 'str'&gt;
  • 你 100% 确定吗?似乎消息正文中的某些内容是字节字符串
  • 是的,100% 确定,&gt;&gt;&gt; type(request_body) &lt;class 'dict'&gt; &gt;&gt;&gt; type(request_body['username']) &lt;class 'str'&gt; &gt;&gt;&gt; type(request_body['password']) &lt;class 'str'&gt; &gt;&gt;&gt; type(request_body['grant_type']) &lt;class 'str'&gt;
  • 我认为您在 POST 中没有正确使用 request()。查看the documentation。我认为您的 request_body 应该是 fields arg

标签: python python-3.x urllib3


【解决方案1】:

我认为您的意思是使用 fields 参数而不是 body

http.request('POST', 'https://api/url/endpoint', headers=request_headers, fields=request_body)

喜欢这个example

【讨论】:

  • +1,它现在发送请求没有错误,但是 api 说请求中缺少grant_type '{"error_description":"Missing grant_type parameter value","error":"invalid_request"}'
  • @Mubin 你知道为什么grant_type 不见了吗?
  • 不,但它正在发送请求,这是主要问题,我会以某种方式解决这个问题..
【解决方案2】:

我已经找到了解决这个问题的方法。 我试图从 keycloak 获取令牌。 Keycloak 除外:
POST 请求
内容类型:application/x-www-form-urlencoded
正文中有凭据

我在https://urllib3.readthedocs.io/en/latest/reference/index.html#module-urllib3.request:

request_encode_body(method, url, fields=None, headers=None, encode_multipart=True, multipart_boundary=None, **urlopen_kw)

使用 urlopen() 请求正文中编码的字段。这对于 POST、PUT、PATCH 等请求方法很有用。

当 encode_multipart=True(默认)时,urllib3.filepost.encode_multipart_formdata() 用于使用适当的内容类型对有效负载进行编码。否则 urllib.urlencode() 与“application/x-www-form-urlencoded”内容类型一起使用。

所以我成功完成了这样的请求:

    data = {
        'client_id': 'front',
        'grant_type': 'password',
        'username': settings.AUTH_REST_ADMIN_API_USER,
        'password': settings.AUTH_REST_ADMIN_API_PASSWORD
    }

    r = http.request_encode_body(
        'POST',
        settings.token_endpoint,
        encode_multipart=False,
        headers={
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': settings.AUTH_AUTHORIZATION
        },
        fields=data
    )

request_encode_body 方法的 encode_multipart=False 部分解决了我的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多