requests.Request 中參數data與json的區別


requests.Request使用參數data傳值

  • 當使用data傳值時,入參為object類型,在發送前,request將參數前置處理,在body中處理成格式為k1=v1&k2=v2 格式,content_type:application/x-www-form-urlencoded

import requests
import json
if __name__ == '__main__':
    playload={
        "person":json.dumps({
            "name":"Milton",
            "age": "18"
        })
    }
    resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
    # resp = requests.post("http://localhost:8000/rftester/dd_msg/", json=json.dumps(playload))

預處理格式如下:

content_type:application/x-www-form-urlencoded
data body: person={"name": "Milton", "age": "18"}

這種情況下,服務端可以通過各個key將參數提取,如person = request.POST.get("person")

  • 注意:當如上字典多層嵌套時,只能解析到第一層,value值必須為字符串,否則會解析出錯,如下

import requests
import json
if __name__ == '__main__':
    playload={
        "person":{
            "name":"Milton",
            "age": "18"
        }
    }
    resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
    # resp = requests.post("http://localhost:8000/rftester/dd_msg/", json=json.dumps(playload))

預處理后,格式如下:

content_type:application/x-www-form-urlencoded
data body: person=name&person=age

這種情況,服務端解析,會解析不到預期的入參,請注意!!!

requests.Request使用參數json傳值

  • 當request使用json傳值時,入參為json字符串,在發送前,request將參數前置處理,在body中處理成格式為json字符串,content_type:application/json

import requests
import json
if __name__ == '__main__':
    playload={
        "person":{
            "name":"Milton",
            "age": "18"
        }
    }
    # resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
    resp = requests.post("http://localhost:8000/rftester/dd_msg/", json=json.dumps(playload))
    print(resp.text)

預處理格式如下:

content_type:application/json
json body: "{\"person\": {\"name\": \"Milton\", \"age\": \"18\"}}"

這種情況,服務端直接解析body,可以解析出合法json字符串,可以轉換成對象。如:body=json.loads(request.body)

修改源碼,使得使用data傳參時,支持解析嵌套字典。

找到源碼位置:site-packages\requests\models.py
_encode_params方法修改如下:

    @staticmethod
    def _encode_params(data):
        """Encode parameters in a piece of data.

        Will successfully encode parameters when passed as a dict or a list of
        2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
        if parameters are supplied as a dict.
        """

        if isinstance(data, (str, bytes)):
            return data
        elif hasattr(data, 'read'):
            return data
        elif hasattr(data, '__iter__'):
            result = []
            for k, vs in to_key_val_list(data):
                if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
                    vs = [vs]
                    for v in vs:
                        if v is not None:
                            result.append(
                                (k.encode('utf-8') if isinstance(k, str) else k,
                                 v.encode('utf-8') if isinstance(v, str) else v))
                if isinstance(vs,dict):
                    result.append((k.encode('utf-8') if isinstance(k, str) else k,
                                 complexjson.dumps(vs).encode('utf-8')))
            return urlencode(result, doseq=True)
        else:
            return data

測試結果如下

import requests
import json
if __name__ == '__main__':
    playload={
        "person":{
            "name":"Milton",
            "age": "18"
        },
        "address":"GZ"
    }
    requests.Request()
    resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)

預處理參數如下:

content_type:application/x-www-form-urlencoded
data body: person={"name": "Milton", "age": "18"}&address=GZ

通過以上修改源碼后,data參數已經可以支持嵌套多層字典!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM