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
相关产品推荐
相关产品推荐

