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

React图片上传报错:FormData.append参数2非Blob类型,求排查

解决React上传图片时FormData.append的Blob类型错误

你遇到的Uncaught TypeError: Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'错误,核心原因是当用户未选择图片就提交表单时,courseData.f_img是空字符串(初始值),而FormData.append要求第二个参数必须是Blob/File类型。以下是具体修复方案及优化后的代码:

修复要点

  • 提交前校验文件状态:在表单提交时先判断文件是否已选择,避免空值传入FormData
  • 修正异步请求的错误捕获:原useEffect中的try/catch无法捕获axios异步请求的错误,改用.catch()处理
  • 移除重复属性:第一个input元素存在重复的name属性,删除多余的空name
  • 完善错误调试:给axios.post添加错误捕获逻辑,打印具体错误信息
  • 优化state初始值:将f_img初始值设为null,更清晰区分未选择文件的状态

优化后的完整代码

import { useEffect, useState } from 'react';
import axios from 'axios'

const baseUrl = 'http://127.0.0.1:8000/api';

function AddCourse() {
    const [cats, setCats] = useState([])
    const [courseData, setCourseData] = useState({
        category:"",
        title:"",
        description:"",
        teacher:"",
        f_img: null, // 初始值设为null
        techs:"",
    })

    // 修正错误捕获逻辑
    useEffect(() => {
        axios.get(baseUrl + '/category/')
            .then((res) => setCats(res.data))
            .catch(error => {
                console.log("加载分类数据失败:", error);
            })
    }, [])

    const handleChange = (event) => {
        setCourseData({
            ...courseData,
            [event.target.name]: event.target.value
        })
    }

    const handleFileChange = (event) => {
        setCourseData({
            ...courseData,
            [event.target.name]: event.target.files[0]
        })
    }

    const formSubmit = () => {
        // 新增:校验文件是否已选择
        if (!courseData.f_img) {
            alert("请选择要上传的图片");
            return;
        }

        const _formData = new FormData()
        _formData.append("category", courseData.category)
        _formData.append("teacher", 1)
        _formData.append("title", courseData.title)
        _formData.append("featured_img", courseData.f_img, courseData.f_img.name)
        _formData.append("description", courseData.description)
        _formData.append("techs", courseData.techs)

        axios.post(baseUrl + '/course/', _formData, {
            headers: {
                'content-type':'multipart/form-data'
            }
        }).then((res) => {
            console.log("课程创建成功:", res.data);
        }).catch(error => {
            // 新增:打印请求错误信息
            console.log("提交课程失败:", error);
        })
    }

    return (
        <div>
            {/* 移除重复的name=""属性 */}
            <input onChange={handleChange} name="title" type="text" className="form-control" id="" />

            <textarea onChange={handleChange} name="description" className="form-control" placeholder="" />

            <select onChange={handleChange} name="category" className="form-control" id="">
                {cats.map((category, index) => (
                    <option key={index} value={category.id}>{category.title}</option>
                ))}
            </select>

            <input onChange={handleFileChange} name="f_img" type="file" className="form-control" id="" />

            <textarea onChange={handleChange} name="techs" className="form-control" placeholder="React, Django, Express" />

            <button onClick={formSubmit} className="btn btn-primary" type="submit">Update</button>
        </div>
    );
}

export default AddCourse;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:45:24