MicroPython发起POST请求时服务端接收请求体为空如何解决
问题根源
你的POST请求不符合HTTP/1.1协议规范,具体错误点如下:
- 缺失必填的
Content-Length请求头:HTTP/1.1 POST请求必须通过该头告知服务端请求体的字节长度,没有这个头时服务端不会读取后续内容,直接判定请求体为空。 - 请求头存在多余非法空格:原代码中
HTTP/1.1 \r\n、Host:XX.XXX.XXX.XXX \r\n、Accept: application/json \r\n等位置的多余空格会导致部分严格的服务端解析请求头失败。 - 请求头和请求体没有明确分隔:原代码直接把JSON内容拼接在最后一个请求头后面,没有用空行(连续
\r\n)标记请求头结束,服务端会把JSON内容识别为非法请求头字段,不会当作请求体处理。
修正后的可运行代码
from network import WLAN import socket import machine import time import json import pycom wlan = WLAN(mode=WLAN.STA) wlan.connect("*****", auth=(WLAN.WPA2, "*****"), timeout=5000) while not wlan.isconnected(): machine.idle() print("Connected to WiFi\n") s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) url = 'XX.XXX.XXX.XXX' sockaddr = socket.getaddrinfo(url, 80)[0][-1] s.connect(sockaddr) print('socket connected') # 构造请求数据,序列化后转字节,避免手动拼接JSON出现格式错误 payload = { "node_id": "1", "value": [ { "measure_time_stamp": "2020-10-06T09:25:43", "temp": "14", "humidity": "75", "ph1": 11, "ph2": 12, "ph3": 13 } ] } payload_bytes = json.dumps(payload).encode('utf-8') # 构造符合HTTP规范的请求 http_req_header = ( b'POST /sensordata/insertrecords HTTP/1.1\r\n' b'Host: XX.XXX.XXX.XXX\r\n' b'Accept: application/json\r\n' b'Content-Type: application/json\r\n' b'Content-Length: %d\r\n' b'\r\n' ) % len(payload_bytes) s.send(http_req_header + payload_bytes) time.sleep(1) rec_bytes = s.recv(4096) print("RESPONSE = " + str(rec_bytes)) print('end') s.close()
编写注意事项
- 不要手动拼接JSON字符串,优先使用
json.dumps()自动序列化,避免引号不匹配、转义字符缺失导致的格式错误。 - HTTP请求头每一行结尾必须是
\r\n,字段名和值之间的冒号后保留1个空格即可,不要添加多余空格,也不要漏写换行。 Content-Length的值必须是请求体的字节长度,不能直接按字符串长度计算,遇到多字节字符时会出现长度不匹配的问题。- 请求头和请求体之间必须保留一个空行(即连续两个
\r\n),用来标记请求头部分结束,之后的内容才会被服务端识别为请求体。
内容的提问来源于stack exchange,提问作者Alessio D.
相关产品推荐
相关产品推荐

