Python:带有自定义标头的请求失败

萨米

我在使用自定义标头进行发布请求时遇到了一些问题。我正在使用Requests库并作为端点jsonplaceholder,您可以在其中获取 POST 请求的假 JSON。

我用我的脚本调用

py request.py

// 请求.py

import requests
import json
from pprint import pprint

def postReqCustom( url, headers, data):
    print('Making request to: ', url)
    r = requests.post(url, headers=headers, data=data)

    print('status code: ' + str(r.status_code))

    response = r.json()
    pprint(response)

def postReq( url, data):
    print('Making request to: ', url)
    r = requests.post(url, data=data)

    print('status code: ' + str(r.status_code))

    response = r.json()
    pprint(response)

headers = {'content-type': 'application/json'}

data = {
            "title": "foo",
            "body": "bar",
            "userId": 1
            }
post_url = "https://jsonplaceholder.typicode.com/posts"

#postReq(post_url, data) #ok
postReqCustom(post_url, headers, data) #error

因为postReq我没有收到任何错误(状态代码 201),但是当我尝试postReqCustom使用自定义标头时,出现以下错误:

Making request to:  https://jsonplaceholder.typicode.com/posts
status code: 500
Traceback (most recent call last):
  File "request.py", line 55, in <module>
    postReqCustom(post_url, headers, payload)
  File "request.py", line 24, in postReqCustom
    response = r.json()
  File "C:\Users\Samy\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\models.py", line 892, in json
    return complexjson.loads(self.text, **kwargs)
  File "C:\Users\Samy\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "C:\Users\Samy\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Users\Samy\AppData\Local\Programs\Python\Python36-32\lib\json\decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
阿巴纳特

问题是您正在使用data=data. 正如文档解释的那样,如果您使用此参数,并传递除字符串以外的任何内容,1它会对您的数据进行形式编码,如下所示:

title=foo&body=bar&userId=1

默认情况下,它还将Content-Type标头设置application/x-www-form-urlencoded,因此一切正常。

但是,如果您使用 覆盖该标头application/json,则现在您title=foo&body=bar&userId=1将向服务器传递正文并告诉它将其解码为 JSON。这当然失败了,所以服务器给你一个错误也就不足为奇了。2


如果您希望您的值采用 JSON 编码而不是表单编码,请使用json参数,而不是data参数:

r = requests.post(url, headers=headers, json=data)

此 JSON 编码您的数据,如下所示:

{"title": "foo", "body": "bar", "userId": 1}

它也将默认Content-Typeapplication/json,所以一切都会正常。当然,如果您使用相同的值覆盖相同的标头,它仍然会以相同的方式工作。


如果您想手动进行编码并发送您编码的任何字符串,您可以使用data,但是您必须发送一个字符串。例如(取自同一文档部分):

r = requests.post(url, headers=headers, data=json.dumps(data))

1. Unicodestr和编码bytesbytes类似类型在这里都被视为字符串,但这在快速入门教程中没有解释。

2. 当然,真正的服务器应该并且可能会返回400 Bad Request,而不是尝试做一些没有意义的事情,得到意外错误,然后只是用500 Internal Server Error.

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章