aiohttp 異步http請求-2.post 請求application/json和application/x-www-form-urlencode


前言

aiohttp 發送post請求,body類型的常見的類型傳參:

  • application/json
  • application/x-www-form-urlencode

application/json

POST 請求接口報文示例,Content-Type類型是application/json

POST /api/v1/login/ HTTP/1.1
Accept: application/json, */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 42
Content-Type: application/json
Host: 127.0.0.1:8000
User-Agent: HTTPie/1.0.3

{
    "password": "123456",
    "username": "test"
}

於是可以使用ClientSession.post()接受 json參數

import aiohttp
import asyncio


async def main():
    async with aiohttp.ClientSession('http://127.0.0.1:8000') as session:
        body = {
                    "password": "123456",
                    "username": "test"
                }
        async with session.post('/api/v1/login', json=body) as resp:
            print(resp.url)
            print(await resp.text())


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

運行結果

http://127.0.0.1:8000/api/v1/login
{"code": 0, "msg": "login success!", "username": "test", "token": "ff7b608ed22407a4cd4d2f7beb1bfe9015574bdc"}

默認情況下,會話使用 python 的標准json模塊進行序列化。但可以使用不同的 serializer.
ClientSession接受json_serialize 參數:

import ujson

async with aiohttp.ClientSession(
        json_serialize=ujson.dumps) as session:
    await session.post(url, json={'test': 'object'})

筆記:ujson 比json快,但有些不兼容

JSON 響應內容

有一個內置的 JSON 解碼器,以防您處理 JSON 數據:

        async with session.post('/api/v1/login', json=body) as resp:
            print(await resp.json())

如果json解碼失敗,會拋出異常ContentTypeError

    raise ContentTypeError(
aiohttp.client_exceptions.ContentTypeError: 0, message='Attempt to decode JSON with unexpected mimetype: text/html; charset=utf-8'

使用.json()解碼器后,會將返回的內容解析成python里面的dict類型,方便取值

        async with session.post('/api/v1/login', json=body) as resp:
            res = await resp.json()
            token = res['token']
            print('token: ', token)

application/x-www-form-urlencode

POST 請求接口報文示例,Content-Type類型是application/x-www-form-urlencode

POST /api/v4/login HTTP/1.1
Content-Length: 29
Content-Type: application/x-www-form-urlencoded

username=test&password=123456

html上form表單數據的提交,只需傳一個data參數即可

import aiohttp
import asyncio


async def main():
    async with aiohttp.ClientSession('http://127.0.0.1:8000') as session:
        body = {
                    "password": "123456",
                    "username": "test"
                }
        async with session.post('/api/v4/login', data=body) as resp:
            print(await resp.json())
            

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

運行結果

{'code': 0, 'msg': 'login success!', 'username': 'test', 'token': '408434b72328ea6740f7f2c260a1c3f97be82fab'}

總結

如果要發送未進行表單編碼的數據,可以通過傳遞 bytes 默認情況下內容類型設置為 'application/octet-stream':

async with session.post(url, data=b'\x00Binary-data\x00') as resp:
    ...

如果要發送 JSON 數據:

async with session.post(url, json={'example': 'test'}) as resp:
    ...

要發送具有適當內容類型的文本,只需使用data參數

async with session.post(url, data='Тест') as resp:
    ...


免責聲明!

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



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