问题描述
我在MT4上调用WebRequest函数将MT4平台上的MqlRates中的数据发送到django平台,在MT4平台发送时就设置了JSON的格式,然而在django后台通过json.loads函数却无法正确的解析出来。错误信息:Extra data: line 1 column 1694 (char 1693),也就是说我们数据并不是正确的JSON格式,下面是我的后台函数:
@csrf_exempt
def receive_quotes(request):
# 获取POST请求中的JSON数据
src = request.body.decode('utf-8')
print(src)
print(cleaned_data)
try:
json_data = json.loads(cleaned_data)
except json.JSONDecodeError as e:
print("Error decoding JSON:", e)
print(json_data)
print("**************************************")
symbol = json_data['symbol']
print(symbol)
尝试过程
1、网上有JSON解析器,直接将数据复制上去,看能不能解析出来,我用的这个:
https://www.json.cn/json/jsononline.html结果可以正常显示为JSON格式。
2、在IDLE上写了一个小demo,代码如下:
import json
data='{ "symbol": "GOLD", "rates": [{ "time": "2023.08.02 09:00:00", "open": 1948.75000, "high": 1948.97000, "low": 1948.74000, "close": 1948.97000, "tick_volume": 31, "spread": 0, "real_volume": 0 },{ "time": "2023.08.02 08:00:00", "open": 1946.28000, "high": 1949.90000, "low": 1946.27000, "close": 1948.78000, "tick_volume": 6574, "spread": 0, "real_volume": 0 },{ "time": "2023.08.02 07:00:00", "open": 1949.27000, "high": 1949.28000, "low": 1945.18000, "close": 1946.29000, "tick_volume": 3716, "spread": 0, "real_volume": 0 },{ "time": "2023.08.02 06:00:00", "open": 1948.18000, "high": 1949.44000, "low": 1946.58000, "close": 1949.27000, "tick_volume": 4494, "spread": 0, "real_volume": 0 },{ "time": "2023.08.02 05:00:00", "open": 1947.54000, "high": 1949.80000, "low": 1947.03000, "close": 1948.19000, "tick_volume": 6357, "spread": 0, "real_volume": 0 },{ "time": "2023.08.02 04:00:00", "open": 1949.14000, "high": 1949.79000, "low": 1947.58000, "close": 1947.60000, "tick_volume": 6730, "spread": 0, "real_volume": 0 },{ "time": "2023.08.02 03:00:00", "open": 1952.12000, "high": 1952.35000, "low": 1948.27000, "close": 1949.17000, "tick_volume": 5801, "spread": 0, "real_volume": 0 },{ "time": "2023.08.02 02:00:00", "open": 1951.14000, "high": 1952.80000, "low": 1950.44000, "close": 1952.10000, "tick_volume": 3464, "spread": 0, "real_volume": 0 },{ "time": "2023.08.02 01:00:00", "open": 1947.38000, "high": 1951.78000, "low": 1945.56000, "close": 1951.08000, "tick_volume": 5473, "spread": 0, "real_volume": 0 },{ "time": "2023.08.01 23:00:00", "open": 1944.36000, "high": 1944.82000, "low": 1943.97000, "close": 1944.24000, "tick_volume": 1335, "spread": 0, "real_volume": 0 } ] }'
print(data)
data_type=type(data)
data_type_str=str(data_type)
print('The type of data is:'+data_type_str)
print("**************************************")
json_data=json.loads(data)
json_data_type=type(json_data)
json_data_type_str=str(json_data_type)
print('The type of json_data is:'+json_data_type_str)
symbol=json_data['symbol']
print(symbol)
结果可以正常的将symbol的值,也就是"GOLD“解析出来。
产生问题的根源
当我在后台函数中调用request.POST时发现,输出的内容和request.body.decode('utf-8')相比终于发现了问题,request.POST获得的内容在结尾处多了一个"\x00",而这个"\x00"就是问题的根源,"\x00"在C风格的字符串中,表示字符串的结尾,但是在JSON数据上下文中,负载末尾不应有空字节。
解决方法
已经找到了问题的根源,解决方法简单粗暴,直接删除对应的字符即可,对原始的数据调用rstrip函数:
cleaned_data = src.rstrip('\x00')
之后就可以正常的解析数据了。
结语
在 Django 中收到的数据末尾出现 x00 可能是由于多种原因造成的:
1、编码问题:这可能是由发送方 (MT4) 和接收方 (Django) 之间的数据编码或解码方式引起的。确保双方一致地使用相同的编码 (UTF-8)。
2、数据格式:确保从 MT4 发送的数据是格式良好的 JSON,末尾没有任何意外字符。
3、尾随字符:检查从 MT4 发送的数据中是否存在任何不属于 JSON 数据的尾随字符。
这一次是由MT4上发送数据到django后台, WebRequest函数采用的是HTTP协议,因此我认为最起码当你使用HTTP协议向网站后台发送数据解析出现问题时,可以检查下是否有这个可恨的"\x00"。