求助:Django 2.0无法正确读取Unity发送的POST请求
解决Django接收Unity POST图片时request.POST/FILES为空的问题
我之前也碰到过一模一样的情况——Unity那边明明按文档发了请求,Django服务器也接收到了,但request.POST和request.FILES就是空的,只有request.body里能看到数据。本质原因是Unity的请求格式和Web表单的默认规范不太匹配,导致Django没法自动解析到这两个属性里,咱们一步步来解决:
核心原因
Django的request.POST和request.FILES只在请求满足以下条件时才会被自动填充:
- 请求的
Content-Type是application/x-www-form-urlencoded(普通表单)或者multipart/form-data(带文件的表单) - 请求体的格式严格符合对应编码的规范
如果Unity发送的是原始二进制图片数据,或者用了其他Content-Type(比如application/octet-stream),Django就不会把这些数据解析到POST/FILES里,只会把原始内容存在request.body中——这就是你看到body有内容但POST/FILES为空的根本原因。
解决方案一:让Unity发送标准的multipart/form-data请求(推荐)
这是最贴合Django处理逻辑的方式,Unity其实原生支持构造这种请求。你可以让Unity端调整代码,把图片作为表单文件字段发送,示例C#代码大概是这样的:
IEnumerator UploadImage(string uploadUrl, Texture2D targetTexture) { // 将Texture转为二进制数据,这里用PNG格式,也可以换成EncodeToJPG() byte[] imageBytes = targetTexture.EncodeToPNG(); WWWForm form = new WWWForm(); // 添加文件字段:字段名、二进制数据、文件名、MIME类型 form.AddBinaryData("uploaded_image", imageBytes, "unity_screenshot.png", "image/png"); using (UnityWebRequest www = UnityWebRequest.Post(uploadUrl, form)) { yield return www.SendWebRequest(); if (www.result != UnityWebRequest.Result.Success) { Debug.LogError($"上传失败:{www.error}"); } else { Debug.Log("图片上传完成!"); } } }
调整后,Django端就能正常从request.FILES里拿到图片了,处理示例代码:
from django.http import HttpResponse import os def receive_image(request): if request.method == 'POST': # 从表单字段里获取图片文件 image_file = request.FILES.get('uploaded_image') if image_file: # 确保保存目录存在 save_dir = './uploads' os.makedirs(save_dir, exist_ok=True) # 写入文件 with open(os.path.join(save_dir, image_file.name), 'wb+') as dest_file: for chunk in image_file.chunks(): dest_file.write(chunk) return HttpResponse("图片上传成功") return HttpResponse("未接收到图片文件") return HttpResponse("仅支持POST请求")
解决方案二:直接解析Django的request.body(如果Unity端无法调整)
如果Unity那边因为业务限制没法改成multipart/form-data,那咱们就在Django这边直接读取request.body的二进制数据:
from django.http import HttpResponse import os def receive_raw_image(request): if request.method == 'POST': # 先确认请求的Content-Type是二进制流类型 if request.content_type == 'application/octet-stream': image_data = request.body # 自定义保存路径和文件名,这里可以和Unity约定好格式 save_path = './uploads/unity_raw_image.png' os.makedirs(os.path.dirname(save_path), exist_ok=True) with open(save_path, 'wb') as save_file: save_file.write(image_data) return HttpResponse("原始图片数据保存成功") return HttpResponse("不支持的Content-Type类型") return HttpResponse("仅支持POST请求")
这种方式需要和Unity端提前约定好图片格式(比如PNG还是JPG),以及请求的Content-Type,避免解析后图片损坏。
额外排查点
- 检查Unity端的请求头:如果用
WWWForm构造请求,不要手动修改Content-Type——WWWForm会自动添加带boundary的正确头,手动修改很容易导致Django解析失败 - 检查Django中间件:有没有自定义中间件提前读取了
request.body?因为request.body只能被读取一次,中间件如果先读了,后续视图里就拿不到完整数据了
内容的提问来源于stack exchange,提问作者jckstl
相关产品推荐
相关产品推荐

