从Flask迁移至AWS Lambda:如何将请求字符串转为JSON/字典?
解析Lambda收到的URL编码表单数据为嵌套字典/JSON
嘿,我完全懂你的困扰!从Flask迁移到Lambda后,最大的差异之一就是Flask会自动帮你解析请求数据成字典,但Lambda只会给你原始的URL编码字符串(还可能带HTML实体转义)。别担心,用Python的标准库就能轻松搞定,步骤如下:
步骤1:预处理字符串(处理HTML实体)
首先你收到的字符串里有&,这是HTML转义后的&符号,得先把它替换回正常的&,不然解析工具会识别错参数分隔符:
import urllib.parse import json # 你收到的原始字符串 raw_request_data = "error%5Bcode%5D=BAD_REQUEST_ERROR&error%5Bdescription%5D=Payment+failed&error%5Bsource%5D=gateway&error%5Bstep%5D=payment_authorization&error%5Breason%5D=payment_failed&error%5Bmetadata%5D=%7B%22payment_id%22%3A%22pay_Es97gMGzx61l1u%22%2C%22order_id%22%3A%22order_Es96Rxp5OmnVVF%22%7D" # 替换HTML转义的&为真实的& cleaned_data = raw_request_data.replace('&', '&')
步骤2:解析URL编码的表单数据
用urllib.parse.parse_qs把字符串解析成基础字典,但要注意这个方法会把每个参数值包装成列表(因为URL允许同一个键多次出现),所以我们要把单个值取出来:
# 解析成初始字典(值为列表) parsed_flat = urllib.parse.parse_qs(cleaned_data) # 把列表值转为单个值 flat_dict = {key: value[0] for key, value in parsed_flat.items()}
步骤3:构建嵌套字典(处理error[xxx]格式的键)
现在你得到的是扁平字典,键是error[code]这种格式,需要把它们转换成嵌套的error字典,同时还要处理metadata字段(它本身是URL编码的JSON字符串):
final_result = {} for key, value in flat_dict.items(): # 检测是否是嵌套键格式(比如error[code]) if '[' in key and ']' in key: parent_key, child_key_part = key.split('[', 1) child_key = child_key_part.rstrip(']') # 初始化父字典(如果不存在) if parent_key not in final_result: final_result[parent_key] = {} # 处理metadata字段:URL解码后解析为JSON if child_key == 'metadata': decoded_metadata = urllib.parse.unquote(value) final_result[parent_key][child_key] = json.loads(decoded_metadata) else: final_result[parent_key][child_key] = value else: final_result[key] = value
最终结果
现在final_result就是你想要的嵌套字典了,要是需要JSON字符串,直接用json.dumps转换:
# 转成格式化的JSON字符串 json_output = json.dumps(final_result, indent=2) print(json_output)
输出会是这样的:
{ "error": { "code": "BAD_REQUEST_ERROR", "description": "Payment failed", "source": "gateway", "step": "payment_authorization", "reason": "payment_failed", "metadata": { "payment_id": "pay_Es97gMGzx61l1u", "order_id": "order_Es96Rxp5OmnVVF" } } }
小提示
如果你的Lambda函数是通过API Gateway触发的,有时候event['body']直接就是这个原始字符串,直接把raw_request_data替换成event['body']就行啦!
内容的提问来源于stack exchange,提问作者Josh Demail
相关产品推荐
相关产品推荐

