Python “安全”序列化复杂对象的问题

gosky · 2024-8-14 17:07:03 · 100 次点击
需求是:
接口里,有多处渲染图片的逻辑
想把渲染图片的逻辑放到一个个单独的渲染接口

原接口返回的响应,原本带了几个图片的 base64 ,现在改为带几个图片的渲染参数
前端拿到渲染参数,拼成一个图片 url ,再请求 ——当然,这里必须是 get ,渲染参数也不能嵌套
渲染接口,接到渲染参数,再渲染图片,返回一个图片响应到前端

渲染参数结构大致是这样的:
{
        code: "123",
        type: "xyz",
    param: "..."
}

这个渲染参数,是一个两层结构
具体的渲染参数都在 param 中,code 和 type 只是用来找到具体的渲染口子
因为渲染接口只能是 get ,param 给前端必须是字符串
后端拿到渲染参数第一步,解析出 code 和 type ,找到渲染口子。渲染口子内部再解析 param
之前没多想,把渲染参数 json 序列化,赋值给 param
没想到 json 序列化渲染参数时,会将 param 的 json 进行转义…… 导致反序列化时,param 反序列化报错

当然,有几个可行的方案:
一、ensure_ascii=False 不转义。这会影响全局。因为渲染参数响应,它的序列化是全局逻辑
二、忽略渲染参数的两层结构,直接完整的序列化和反序列化
三、param 先 json 序列化,再 base64 安全编码。这个问题是多了一部操作,且输出结果人类不可读
四,反序列化 param 时,先反转义

求一个更加优雅的方案

我需要的,也许是一个“安全”的序列化方法, 能将 param 数据,序列化为不需要转义的数据。但 python 没有 safe 的 json 方法。base64 倒是一般都有
js 有一个库,https://www.npmjs.com/package/qs ,可以将 js 嵌套对象、数组对象编码为查询字符串
但 python 好像没这样的库
举报· 100 次点击
登录 注册 站外分享
4 条回复  
tianzhongs 小成 2024-8-14 17:21:56
可以使用自定义的编码方式来处理这个问题。思路如下:
对于 param 中的数据,将其键值对按照一定规则拼接成字符串,而不是直接使用 JSON 序列化。
例如,如果 param 是 {"key1": "value1", "key2": "value2"},可以将其拼接为 key1=value1&key2=value2 的形式。
在前端和后端约定好这个编码规则。
前端在发送请求时,按照这个规则将 param 中的数据拼接成字符串,然后将整个渲染参数对象构建成 URL 的查询参数形式。
后端接收到请求后,先解析出 code 和 type ,然后根据约定的规则将 param 部分的字符串再解析回键值对的形式。
这样做的好处有:
不需要依赖复杂的第三方库或者特殊的设置(如 ensure_ascii=False ),并且完全符合只能使用 GET 请求且参数不能嵌套的要求。
避免了 JSON 序列化可能带来的转义问题,同时也没有增加过多的复杂操作(相比于先序列化再 base64 编码的方式)。
输出的结果相对简洁且人类可读程度较高,只要了解规则,在调试等情况下也比较容易理解。
sagaxu 初学 2024-8-14 17:25:22
JSON 编码解码,是 JSON 规范,不会因为转义不转义失败。
URL 的 Query String ,也有自己的编码规范。

两件事情是完全不相干的,要分别处理,难不成你指望 JSON 序列化后的东西直接拼 URL 里用?
tolbkni 小成 2024-8-14 17:30:57
```python
from urllib.parse import parse_qs
y = parse_qs('a=c')
```
MoYi123 小成 2024-8-14 17:46:51
问题最关键的 param 是怎么样子的, 让你用 param: "..." 这样三个点跳过了.
返回顶部