Python使用json.dumps发请求至SAP报格式错误如何解决
问题根因
你遇到的报错和斜杠转义没有直接关系,核心是两个容易踩的开发坑:
- 你最开始手动给字符串加的
\/本身就是多余的:JSON规范允许对/做转义写成\/,Python的json.dumps()默认会自动把字符串里的/转成\/,如果你在Python字符串里提前写了\/,Python会把反斜杠识别为字符串内容的一部分,最后序列化出来就变成\\/(双反斜杠加斜杠),这才是你一开始看到请求体里多出来反斜杠的原因。你后面把时间戳里的反斜杠删掉,直接写"/Date(xxx)/"的写法是对的,这时候json.dumps()自动转出来的\/完全符合JSON标准,SAP OData接口本身可以正常解析这种格式。 - Postman发送成功但Python代码失败的核心原因是缺失正确的
Content-Type请求头:Postman发JSON请求时会自动带上Content-Type: application/json头,但你之前的代码只传了data=json.dumps(payload),requests库在接收到字符串类型的data参数时,默认会把Content-Type设为text/plain或者application/x-www-form-urlencoded,SAP接口对请求头校验非常严格,哪怕请求体内容完全一致,只要Content-Type不符合要求,就会直接返回语法格式错误。你排查后端日志看不到差异也很正常,日志默认只会记录请求体正文,不会打印请求头字段。
修复方案
只需要改两处即可:
- 把payload里时间戳字符串中手动加的反斜杠全删掉,直接写普通的
/Date(xxx)/格式即可,不需要手动做转义 - 发POST请求时优先使用requests自带的
json参数传字典,requests会自动完成JSON序列化、自动加上正确的Content-Type: application/json头,不需要手动调用json.dumps()。
修改后的可运行代码片段:
import json import requests SERVICE_URL = "XXX" HEADER = {'apikey': 'XXX'} # 注意时间戳字段不要手动加反斜杠 payload = { "ID" : "f760caa6-a54b-1eec-bef6-b7292029844f", "DeviceID" : "f760caa6-a54b-1eec-bef6-a9fe0249a440", "Type" : "FILL_LVL", "MeasureTimestamp" : "/Date(1656951856000+0000)/", "CreationTimestamp" : "/Date(1656951852000+0000)/", "Value" : "14.000000" } session = requests.Session() session.headers.update(HEADER) response = session.head(SERVICE_URL, headers={'x-csrf-token': 'fetch'}) token = response.headers.get('x-csrf-token', '') session.headers.update({'x-csrf-token': token}) # 直接传json参数,无需手动dumps x = session.post(SERVICE_URL, json=payload) print(x.text)
如果你坚持要手动用json.dumps()处理请求体,记得在请求头里手动补上'Content-Type': 'application/json',否则还是会触发格式报错。
内容的提问来源于stack exchange,提问作者John Bauer
相关产品推荐
相关产品推荐

