如何通过fetch实现React Native(Expo)上传图片到Node.js服务器
图片上传失败问题修复方案
1. 图片选择模块逻辑修复
当前代码选图后仅存储了localUri字段,上传时调用的uri/title/type均为不存在的属性,导致FormData传入无效值,修正后代码如下:
function PickImage() { let [selectedImage, setSelectedImage] = useState(null); let openImagePickerAsync = async () => { let permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (permissionResult.granted === false) { alert("需要获取相册访问权限!"); return; } let pickerResult = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, // 限制仅选图片,保证文件类型正确 }); if (pickerResult.cancelled === true) { return; } // 存储后续上传需要的所有字段 setSelectedImage({ uri: pickerResult.uri, // 从uri提取文件名,避免title字段不存在的问题 name: pickerResult.uri.split('/').pop(), // 统一设置正确的文件类型,可根据实际图片格式调整 type: 'image/jpeg' }); }; // 补充原代码缺失的组件返回逻辑 return ( <TouchableHighlight style={[ styles.profileImgContainer, { borderColor: "#4632a1", borderWidth: 1 }, ]} onPress={openImagePickerAsync} > <Image source={{ uri: selectedImage?.uri }} style={styles.thumbnail} /> </TouchableHighlight> ) }
2. 上传请求逻辑修复
- 禁止手动设置
Content-Type: multipart/form-data请求头,FormData请求会自动生成带正确边界标识(boundary)的请求头,手动设置会丢失边界信息导致multer无法解析表单 - 新增非空判断,避免未选图时发起无效请求
修正后代码如下:
async function upload() { if(!selectedImage) { alert('请先选择图片'); return; } const data = new FormData(); data.append("image", { uri: selectedImage.uri, name: selectedImage.name, type: selectedImage.type, }); const setting = { method: "POST", // 删除手动设置的Content-Type头,由环境自动生成 body: data, }; try { const fetchResponse = await fetch(url, setting); const resData = await fetchResponse.json(); alert(JSON.stringify(resData)); } catch (e) { alert(e); } }
3. 服务端逻辑修复
- 使用
upload.single('image')配置后,上传的文件存储在req.file对象中,req.body仅存放普通表单字段,原代码取req.body.image必然为空 - 需确认multer初始化时已经配置了正确的存储路径,否则文件不会存入本地文件夹
multer初始化参考配置
const multer = require('multer'); // 配置磁盘存储路径和文件名规则 const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, './uploads') // 需提前在项目根目录创建uploads文件夹 }, filename: function (req, file, cb) { cb(null, Date.now() + '-' + file.originalname) } }) const upload = multer({ storage: storage })
接口修正代码
app.post("/users", upload.single("image"), async (req, res) => { console.log('上传的文件信息:', req.file); // 文件信息存在req.file中 console.log('普通表单字段:', req.body); const img = req.file; if (!img) { console.log("no image"); return res.status(400).send({ error: "未获取到上传的图片" }); } res.send({ congrats: "data recieved", fileInfo: img }); });
内容的提问来源于stack exchange,提问作者zeeshan zamurd
相关产品推荐
相关产品推荐

