向服务器上传图片时db.json中图片缺失,如何修复代码?
修复表单提交图片缺失的问题
核心问题分析
你的代码存在两个关键问题导致图片无法存入db.json:
- 手动设置了错误的
Content-Type头:使用FormData提交文件时,axios会自动生成包含boundary的multipart/form-data请求头,你手动指定application/json会让服务器无法解析FormData中的文件数据。 - json-server本身不支持直接存储文件:
db.json是纯JSON格式文件,只能保存字符串、数字等基础类型,无法直接存储二进制文件。
修复方案
方案一:移除错误请求头 + 后端文件上传处理
如果你的后端是自定义Node.js服务器(比如Express),可以用multer中间件处理文件上传,前端仅需修改createPost函数:
const createPost = async (title, image, description) => { const data = new FormData(); data.append('title', title); data.append('image', image); data.append('description', description); // 移除手动设置的Content-Type,让axios自动生成正确的请求头 const response = await axios.post('http://localhost:3001/posts', data); const updatedPosts = [...posts, response.data]; setPosts(updatedPosts); };
后端(Express)需添加multer处理文件上传,示例代码:
const express = require('express'); const multer = require('multer'); const fs = require('fs'); const path = require('path'); const app = express(); // 配置文件存储目录与命名规则 const storage = multer.diskStorage({ destination: (req, file, cb) => { const uploadDir = 'uploads/'; if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir); cb(null, uploadDir); }, filename: (req, file, cb) => { // 用时间戳+原文件名避免重复 const uniqueName = `${Date.now()}-${file.originalname}`; cb(null, uniqueName); } }); const upload = multer({ storage }); // 处理帖子提交接口 app.post('/posts', upload.single('image'), (req, res) => { const { title, description } = req.body; // 将文件相对路径存入db.json const imageUrl = `/uploads/${req.file.filename}`; // 读取并更新db.json const dbPath = path.join(__dirname, 'db.json'); const db = JSON.parse(fs.readFileSync(dbPath, 'utf8')); const newPost = { id: Date.now(), title, image: imageUrl, description }; db.posts.push(newPost); fs.writeFileSync(dbPath, JSON.stringify(db, null, 2)); res.json(newPost); }); app.listen(3001, () => console.log('Server running on port 3001'));
方案二:将图片转为Base64字符串存储(适合小图片)
如果不想修改后端,可直接把图片转成Base64字符串存入db.json,步骤如下:
- 修改前端图片处理逻辑:
const uploadImage = (e) => { const file = e.target.files[0]; const reader = new FileReader(); // 读取文件为Base64字符串 reader.onload = (event) => { setImage(event.target.result); }; reader.readAsDataURL(file); };
- 修改
createPost函数,直接提交JSON数据:
const createPost = async (title, image, description) => { // 直接传JSON对象,无需FormData const response = await axios.post('http://localhost:3001/posts', { title, image, description }, { headers: { 'Content-Type': 'application/json', }, }); const updatedPosts = [...posts, response.data]; setPosts(updatedPosts); };
额外检查点
- 确保Form组件中正确定义
title和description状态:
const [title, setTitle] = useState(''); const [description, setDescription] = useState('');
- 表单中添加对应输入框并绑定状态:
<div className="title"> <label>Title</label> <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} /> </div> <div className="description"> <label>Description</label> <textarea value={description} onChange={(e) => setDescription(e.target.value)} /> </div>
内容的提问来源于stack exchange,提问作者Naufal Fadhil
相关产品推荐
相关产品推荐

