Django 3.1处理NodeMCU ESP8266 POST的RFID UID并渲染模板
Django接收NodeMCU RFID POST请求的修复方案
核心阻塞问题:CSRF校验拦截
这是硬件对接Web服务时最常见的拦截问题,也是你当前收不到POST数据的核心原因
- Django默认开启CSRF安全校验,所有来自外部的POST请求必须携带页面内置的CSRF token才能通过校验,NodeMCU发送的请求没有携带这个token,会被直接拦截返回403错误,根本不会进入你写的视图函数逻辑。
- 修复方式:给需要接收硬件POST请求的视图添加
csrf_exempt装饰器,跳过CSRF校验,修改后的views.py代码如下:
from django.shortcuts import render from django.views.decorators.csrf import csrf_exempt from django.http import HttpResponse from django.core.cache import cache # 豁免CSRF校验,接收NodeMCU发来的POST请求 @csrf_exempt def card_reg(request): # 仅在POST请求时读取硬件上传的UID,普通GET访问返回默认占位符 if request.method == "POST": uid = request.POST.get("UIDresult", "") else: uid = "whatever" context = { "id": uid } return render(request, "nodemcuapp/card_reg.html", context) # 对应urls里已定义的read_card路径,用于独立接收RFID数据 @csrf_exempt def card_read(request): if request.method == "POST": received_uid = request.POST.get("UIDresult", "") # 把收到的最新UID缓存5分钟,供注册页面调用 cache.set("latest_rfid_uid", received_uid, timeout=300) return HttpResponse("OK")
网络连通性调试步骤
- 确认Django启动命令为
python manage.py runserver 0.0.0.0:8080,如果只绑定127.0.0.1,局域网内的NodeMCU设备无法访问服务 - 关闭电脑系统防火墙,或放行8080端口的入站访问规则
- 直接通过NodeMCU串口打印的
httpCode值定位问题:- 返回
403:CSRF拦截问题,按上面的代码修改后重试 - 返回
-1:网络连通异常,检查Django服务是否正常启动、Arduino代码里写的服务IP和端口是否和实际一致、NodeMCU和电脑是否处于同一个局域网 - 返回
200:请求已成功送达Django,此时视图内获取到的id值就是NodeMCU上传的RFID字符串
- 返回
逻辑优化建议
当前的流程存在时序问题:NodeMCU发完POST后才会返回注册页面,如果用户先打开了注册页面、再扫卡,页面不会自动更新UID。可以调整为独立接口存数据、页面读缓存的模式:
- Arduino端把POST请求地址从
http://192.168.1.8:8080/card_registration/改为http://192.168.1.8:8080/read_card - 修改
card_reg视图逻辑,从缓存中读取最新的RFID UID渲染到模板,用户打开注册页面时就能自动加载最近扫描的卡片ID - 模板中不用修改原有的textarea渲染逻辑,
{{id}}会自动填充缓存里的UID值
Arduino侧确认点
- 你当前发送的
postData = "UIDresult=" + UIDresultSend格式是标准的application/x-www-form-urlencoded格式,和Django通过request.POST.get()读取数据的要求完全匹配,不需要调整格式 - 不需要额外在请求里加任何header,只要保留当前的
Content-Type头就能被Django正常解析
内容的提问来源于stack exchange,提问作者Khel Parian
相关产品推荐
相关产品推荐

