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

Django对接React上传图片触发utf-8解码错误如何排查修复

错误根因

这个UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0报错的核心是:0xff是JPEG等常见二进制图片格式的文件头字节,Django侧没有将请求识别为文件上传请求,把二进制图片内容当成UTF-8编码的文本尝试解码,最终触发报错。
具体问题点分三部分:

  • 后端序列化器继承错误:当前ImgSerializer继承的是基础serializers.Serializer,其内部定义的Meta类完全不生效,DRF会将上传的文件字段按普通文本字段做校验,触发解码逻辑。
  • 前后端字段不匹配+视图逻辑错误:模型中图片字段名为image,后端取文件、前端传参的字段名都用的img,字段映射关系断裂;同时视图类定义缺少冒号、未按ModelViewSet要求声明queryset和serializer_class,本身就无法正常运行。
  • 前端请求配置错误:
    • useState初始值设为空字符串,后续却按对象结构做展开赋值,存在逻辑隐患
    • 依赖axios发异步请求时,默认会带上Content-Type: application/json请求头,没有配置multipart/form-data头,Django不会走文件上传解析逻辑;而form标签上的encType属性只对原生表单提交生效,对ajax请求完全无效
    • 存入状态的文件被包裹在对象结构中,append到FormData时传入的是整个JS对象而非File实例,数据格式不符合要求
修复方案

按前后端分别修正代码即可解决:

后端(Django)修正

  1. 修复序列化器,继承模型序列化器,自动映射模型字段:
# serializer.py
from rest_framework import serializers
from . import models

class ImgSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.ImageModel
        fields = '__all__'
  1. 修复视图逻辑,补全ModelViewSet必要配置,统一字段名,复用序列化器的保存逻辑:
# views.py
from rest_framework import viewsets, status
from rest_framework.response import Response
from . import models, serializer

class ImgView(viewsets.ModelViewSet):
    queryset = models.ImageModel.objects.all()
    serializer_class = serializer.ImgSerializer

    def create(self, request, *args, **kwargs):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response("Success", status=status.HTTP_201_CREATED)
        return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST)
  1. 确认基础配置正确:
    • settings.py中已注册rest_framework应用
    • 已配置MEDIA_URL、MEDIA_ROOT参数,保证文件能正常存储
    • 开发环境下在urls.py中配置了媒体文件路由,可正常访问上传后的资源

前端(React)修正

修正状态逻辑、请求配置,统一字段名,保证上传的是标准FormData格式文件:

import { useState } from 'react'
import axios from 'axios'

function ComponentImage(){
    // 初始值直接设为null,单独存储选中的文件实例
    const [img, setImg] = useState(null)

    const handleFileChange = (e) => {
        setImg(e.target.files[0])
    }

    const submitChange = async (e) => {
        e.preventDefault()
        if (!img) return
        
        const formData = new FormData()
        // 字段名和后端模型字段对齐为image
        formData.append('image', img)
        
        await axios.post('http://127.0.0.1:8000/', formData, {
            headers: {
                // 关键:指定multipart类型,不要手动设置boundary,由浏览器自动生成
                'Content-Type': 'multipart/form-data'
            }
        })
    }

    return(
        <div>
            <form onSubmit={submitChange}>
                <div className='divlbl'>
                    <label htmlFor="upload" className='imglbl'>Upload An Image</label>
                </div>
                <input 
                    id='upload' 
                    required 
                    type='file' 
                    name='image'  
                    accept="image/*" 
                    onChange={handleFileChange}
                />
                <button type="submit">上传</button>
            </form>
        </div>
    )
}

修复完成后重新发起请求,Django可正确识别文件上传请求,从request.FILES中拿到二进制文件实例,不会再触发UTF-8解码错误。

内容的提问来源于stack exchange,提问作者Ghazi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:30:57