如何在FastAPI中使用aiohttp将JSON放入查询参数发送请求
解决FastAPI中用aiohttp向查询参数传递JSON字符串的问题
问题分析
你遇到的错误Attempt to decode JSON with unexpected mimetype: text/html,本质是目标API返回了HTML格式的响应(大概率是错误页面,比如400请求参数无效),而非预期的JSON格式。核心原因可能是:
- 查询参数的JSON字符串编码不符合API要求
- 错误设置了
content-type: application/json请求头(GET请求无请求体,该头多余)
解决方案
1. 先排查API返回的具体错误
先修改代码打印响应状态码和文本,明确API返回的错误信息:
async with aiohttp.ClientSession() as session: async with session.request(method, URL, params=params, timeout=5) as response: print(f"响应状态码: {response.status}") print(f"响应内容: {await response.text()}") try: response_data = await response.json() except Exception as e: print(f"JSON解析失败: {e}")
通过输出可以确认是参数格式错误还是API内部问题。
2. 修正请求参数与请求头
- 移除多余的
content-type头:GET请求的查询参数不需要该头,API可能因该头返回错误。 - 确保JSON字符串正确编码:直接传递
json.dumps()生成的JSON字符串,aiohttp会自动处理URL编码,无需手动加单引号(除非API明确要求带单引号)。
修正后的代码:
import json import aiohttp # 构造查询参数:直接传递JSON字符串 params = { "key1": json.dumps({"a": "1", "b": "2"}), "key2": json.dumps({"a": "4", "b": "5"}) } async def call_target_api(): async with aiohttp.ClientSession() as session: async with session.request( method, URL, params=params, timeout=5 ) as response: if response.status == 200: try: response_data = await response.json() # 处理返回的JSON数据 print(response_data) except Exception as e: print(f"JSON解析失败: {e}") print(f"响应内容: {await response.text()}") else: print(f"API错误状态码: {response.status}") print(f"错误内容: {await response.text()}")
3. 若API要求带单引号的JSON字符串
如果目标API确实需要像示例中那样带单引号的格式(key1='{"a": "1"}'),则手动给JSON字符串包裹单引号:
params = { "key1": f"'{json.dumps({'a': '1', 'b': '2'})}'", "key2": f"'{json.dumps({'a': '4', 'b': '5'})}'" }
内容的提问来源于stack exchange,提问作者Abinash Biswal
相关产品推荐
相关产品推荐

