Django无法读取JavaScript提交的form-data格式文件报错排查
问题原因
- 提交函数获取文件对象错误:
document.getElementById("pfp").value拿到的是虚拟路径字符串,不是真实的文件二进制对象,无法通过FormData上传 - 请求函数错误将FormData转为字符串:
data=data.toString()会把FormData直接转为[object FormData]纯文本,后端无法解析出文件内容 - 手动设置了错误的请求头:发送FormData时不需要手动指定
multipart/form-data类型头,浏览器会自动生成带边界标识符(boundary)的正确头,手动设置会导致Django无法解析表单 - 后端未做空值校验:拿到
request.FILES.get("Image")后未判断是否为空就直接传入图片处理函数,空值触发PIL属性错误
修复代码
提交函数修复
function sumbit() { var errorhandler = document.getElementById("Error") var user = document.getElementById("user").value; // 修复:获取真实文件对象 var file = document.getElementById("pfp").files[0]; if(!user || !file) { errorhandler.innerHTML = "用户名和头像不能为空"; return; } var formData = new FormData(); formData.append("Image",file); request = PostData(`http://127.0.0.1:8000/api/makeuser/${user}/`,'POST',formData) if(request == "555") { errorhandler.innerHTML = "Image or User required to make account"; } else if(request=="556") { errorhandler.innerHTML = "User already in use"; } else if(request=="Made") { window.location= "http://127.0.0.1:8000/joinroom/" }else { errorhandler.innerHTML = "Unkown error"; } }
请求函数修复
function PostData(url, method="get", data="") { url=url.toString(); method=method.toString(); // 修复:删除FormData转字符串的逻辑 // data=data.toString(); function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = ''; try { var csrffield = document.getElementsByTagName("input"); var l = csrffield.length; var i=0; while (i <= l) { if (csrffield[i]?.name?.toLowerCase().includes("csrf") == true) { csrftoken=csrffield[i].value; break; } i++; } } catch (err) { csrftoken = getCookie('csrftoken'); } var req = new XMLHttpRequest(); if (method.toLowerCase() == "get") { // 可选修复:把第三个参数改为true使用异步请求,消除同步XHR警告 req.open("GET", url, false); req.send(); if (req.status == 200) { return req.responseText; } } if (method.toLowerCase() == "post") { req.open("POST", url, false); // 修复:删除手动设置的multipart/form-data头 // req.setRequestHeader('Content-Type','multipart/form-data') req.setRequestHeader("X-CSRFToken", csrftoken); req.send(data); return req.responseText; } }
后端接口修复
@csrf_exempt def makeAccountApi(request,User): try: if not User or User.isspace(): return HttpResponse("555") except: return HttpResponse("555") if request.method == 'POST': Image=request.FILES.get("Image") # 修复:添加空值校验 if not Image: return HttpResponse("555") if file_size(Image,2) == 1: return HttpResponse("212") try: accounts.objects.get(user=User) return HttpResponse('556') except: IMG=RESIZE(Image) token=BasicToken() room = accounts(user=User,image=IMG,token=token) room.save() return HttpResponse('Made') else: return HttpResponse("12")
内容的提问来源于stack exchange,提问作者tahabashar11
相关产品推荐
相关产品推荐

