python - 使用具有多个 header 的 urllib 发出 POST 请求会出现 400 Bad Request 错误

标签 python python-3.x post http-headers urllib

我用过requests库,我知道如何使用它,但我只需要使用标准库,所以如果您不鼓励我使用 requests,我将不胜感激。反而。

我制作了一个处理 POST 请求的 Flask 服务器,然后从另一个脚本调用 urllib 对 Flask 服务器进行 POST 调用。 我需要在正文中发送原始 json,就像我们在 Postman 中所做的那样。

Flask 服务器

from flask import Flask, request

app = Flask(__name__)
@app.route('/random', methods=['POST'])
def random():
    if request.method == 'POST':
        if request.headers.get('Authorization') and request.headers.get('Content-Type') == 'application/json':
            print(request.get_json())
            return "Success"
        else:
            print(request.get_json())
            return "Bad request"

app.run(host='0.0.0.0', port=5000, debug=True)

Urllib 客户端(另存为 test.py)-

import urllib.request
import urllib.parse
d = {"spam": 1, "eggs": 2, "bacon": 0}
data = urllib.parse.urlencode(d)
data = data.encode()
req = urllib.request.Request("http://localhost:5000/random", data)
req.add_header('Content-Type', 'application/json')
req.add_header('Authorization', 12345)
with urllib.request.urlopen(req) as f:
    print(f.read().decode('utf-8'))

仅使用 Authorization header ,我得到 Bad Request作为输出,json 是 None在 Flask 服务器端如预期

仅使用 Content-Type header 或两个 header 时,我会收到此错误 -

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    with urllib.request.urlopen(req) as f:
  File "C:\ProgramData\Anaconda3\lib\urllib\request.py", line 223, in urlopen
    return opener.open(url, data, timeout)
  File "C:\ProgramData\Anaconda3\lib\urllib\request.py", line 532, in open
    response = meth(req, response)
  File "C:\ProgramData\Anaconda3\lib\urllib\request.py", line 642, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\ProgramData\Anaconda3\lib\urllib\request.py", line 570, in error
    return self._call_chain(*args)
  File "C:\ProgramData\Anaconda3\lib\urllib\request.py", line 504, in _call_chain
    result = func(*args)
  File "C:\ProgramData\Anaconda3\lib\urllib\request.py", line 650, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: BAD REQUEST

整个事情很简单,但我无法理解为什么会发生这种情况,并且错误消息也没有多大帮助。

最佳答案

服务器在 request.get_json() 中失败。仅当客户端发送两个 header 时才会发生这种情况,因为此时它到达了这一行。

要修复此问题,请将客户端更改为以 JSON 形式发送数据:

import json            # <-- Import json
import urllib.request
import urllib.parse

d = {"spam": 1, "eggs": 2, "bacon": 0}
data = json.dumps(d)   # <-- Dump the dictionary as JSON
data = data.encode()
req = urllib.request.Request("http://localhost:5000/random", data)
req.add_header('Content-Type', 'application/json')
req.add_header('Authorization', 12345)
with urllib.request.urlopen(req) as f:
    print(f.read().decode('utf-8'))

希望这有帮助

关于python - 使用具有多个 header 的 urllib 发出 POST 请求会出现 400 Bad Request 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53500184/

相关文章:

python - 使用 PIL 在 python 2.7 中将文本写入图像

python - 从 sys.stdin 读取,用 RETURN 结束用户输入

python - opencv cascade.detectMultiScale 创建错误 : (-215) ! empty()

javascript - 为什么我的异步 (NodeJS-Python) WebSocket 没有立即连接?

python - 在 Python 3.x 中对二维数组求和

python - Process using multiprocessing 没有输出

python - 如何从 fastapi 响应返回 PIL 图像文件列表?

java - 在 Java 中使用 JSON 的 HTTP POST

android - Android Volley 如何处理暂时失去网络连接?

javascript - 无法通过 PHP 编辑 JSON 数组