You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 11:15:04