Django环境下Ajax POST请求不生效,无法提交图片base64字符串求助
问题排查&修复方案
1. 表单默认提交未阻止
你在onsubmit绑定的函数没有阻止默认行为,所以表单会走原生提交,Ajax请求发了也会因为页面跳转被中断。
2. CSRF参数获取错误
Django渲染的csrf token的name属性是csrfmiddlewaretoken,你代码里写成了csrftoken,会导致获取失败报403错误。
3. 提交格式与后端读取逻辑不匹配
你设置了contentType为application/json,Django的request.POST只能读取表单格式的数据,JSON数据需要从request.body里手动解析。
4. 表单字段定义不匹配
你要传base64字符串,但是AddForm里image字段定义为FileField,校验会直接失败。
5. 缺少图片转base64的逻辑
你代码里用了dataurl变量,但是没有对应的文件选择后转base64的实现,变量未定义会导致Ajax报错。
6. 表单输入项缺失
原有表单没有recipe和caption对应的输入框,会导致JS读取元素时报错。
修改后的add.html
<form method="post" enctype="multipart/form-data" id="postForm"> {% csrf_token %} <input type="text" name="dish" required id="id_dish" placeholder="Rezeptname"> <input type="file" name="image" required id="id_image" accept="image/*"> <div class="image-upload"><img id="img_id" src="#"></div> <!-- 补全缺失的输入项 --> <textarea name="recipe" id="id_recipe" required></textarea> <input type="text" name="caption" id="id_caption" required> <button type="submit">Upload</button> </form> <!-- 请确保你已经提前引入jQuery库 --> <script> // 图片转base64逻辑 let dataurl = '' $('#id_image').change(function () { const file = this.files[0] const reader = new FileReader() reader.onload = function (e) { dataurl = e.target.result $('#img_id').attr('src', dataurl) } reader.readAsDataURL(file) }) // 绑定表单提交事件,阻止默认行为 $('#postForm').submit(function (e) { e.preventDefault() // 核心:阻止原生表单提交 $.ajax({ type: "POST", url: "{% url 'add' %}", // 用表单格式提交,后端可直接通过request.POST读取 data: { csrfmiddlewaretoken: $('input[name="csrfmiddlewaretoken"]').val(), "dish": $('#id_dish').val(), "image": dataurl, "recipe": $('#id_recipe').val(), "caption": $('#id_caption').val() }, success: function (res) { if (res.code === 0) { // 提交成功后跳转首页 window.location.href = "{% url 'home' %}" } else { alert(res.msg) } } }); }) </script>
修改后的forms.py
from django import forms from .models import Post class AddForm(forms.ModelForm): dish = forms.CharField() # 把FileField改为CharField,接收base64字符串 image = forms.CharField() caption = forms.CharField() recipe = forms.CharField() class Meta: model = Post fields = ["dish", "image", "recipe", "caption"]
修改后的views.py
from django.contrib import messages from django.contrib.auth.decorators import login_required from django.http import JsonResponse from django.shortcuts import redirect, render from .models import Client, Post from .forms import AddForm @login_required(login_url="login") def add(request): if request.method == "POST": form = AddForm(request.POST) if form.is_valid(): current_user = Client.objects.get(id=request.user.id) current_user.post_set.create( poster=request.user.username, dish=form.cleaned_data.get("dish"), image=form.cleaned_data.get("image"), caption=form.cleaned_data.get("caption"), recipe=form.cleaned_data.get("recipe") ) # Ajax请求不能直接返回重定向,交由前端控制跳转 return JsonResponse({"code": 0, "msg": "提交成功"}) else: return JsonResponse({"code": 1, "msg": "表单校验失败", "errors": form.errors}) else: form = AddForm() return render(request, "main/add.html", {"form": form})
额外注意
你的Post模型中image字段需要设置为TextField类型,不要使用ImageField/FileField,否则存储长度不足会截断base64字符串导致图片无法正常显示。
内容的提问来源于stack exchange,提问作者Moritz_1201
相关产品推荐
相关产品推荐

