Node.js 使用Multer进行React挂钩和Axios图像上传
我正在尝试添加上载图像的功能,然后使用该图像路径更新用户对象。当我使用失眠客户端上传图像并发送请求时,我能够成功地将图像和路径添加到MongoDB。NodeJS用户路由如下:Node.js 使用Multer进行React挂钩和Axios图像上传,node.js,reactjs,react-hooks,Node.js,Reactjs,React Hooks,我正在尝试添加上载图像的功能,然后使用该图像路径更新用户对象。当我使用失眠客户端上传图像并发送请求时,我能够成功地将图像和路径添加到MongoDB。NodeJS用户路由如下: const express = require ("express"); const router = express.Router(); const bcrypt = require("bcryptjs"); const jwt = require("jsonweb
const express = require ("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const Users = require("../models/users");
const auth = require("../middleware/auth");
const multer = require('multer');
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './uploads/');
},
filename: function(req, file, cb){
cb(null, file.originalname);
}
});
const fileFilter = (req, file, cb) => {
// reject a file
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png' || file.mimetype == "image/jpg") {
cb(null, true);
} else {
cb(null, false);
return cb(new Error('Only .png, .jpg and .jpeg format allowed!'));
}
};
const upload = multer({storage: storage, limits: {
fileSize: 1024 * 1024 * 5
},
fileFilter: fileFilter
});
// REQUEST TO FIND USER BY ID AND ADD A PROFILE PICTURE
router.put('/update/:id', upload.single('userImage'), (req, res) => {
Users.findById(req.params.id)
.then(user => {
user.userImage = req.file.path || user.userImage,
user
.save()
.then(() => res.json("The User is UPDATED succesfully!"))
.catch(err => res.status(400).json(`Error: ${err}`));
})
.catch(err => res.status(500).json(`Error: ${err}`));
console.log(req.body);
console.log(req.file);
});
但是,当我在客户端上测试代码时,我收到以下500个错误:“错误:TypeError:无法读取未定义的属性‘path’。”我正在使用React挂钩和Axios,代码如下:
import React, { useState, useContext } from 'react';
import Exit from '../cancel.svg';
import Modal from 'react-modal';
import { useForm } from "react-hook-form";
import axios from 'axios';
import UserContext from "../context/UserContext";
import { useHistory } from "react-router-dom";
Modal.setAppElement('#root');
const ProfilePicture = () => {
const [modalIsOpen, setModalIsOpen]= useState (true);
const { register, handleSubmit } = useForm ();
const [userImage, setUserImage] = useState();
const onSubmit = (data) => console.log(data);
const { userData } = useContext(UserContext);
const history = useHistory();
const changeOnClick = e => {
const users = {
userImage
};
console.log(users);
axios
.put(`http://localhost:5000/users/update/${userData.user.id}`, users)
.then(res => console.log(res.body))
.catch(err => {
console.log(err);
});
history.push("/Landing")
}
return(
<Modal isOpen={modalIsOpen} onRequestClose={() => setModalIsOpen(false)} className='finishBorder'>
<div className='border-bottom-two'>
<img onClick= {() => setModalIsOpen(false)} className='newexitButton'src={Exit} alt='X' />
<span className='lastThing'>One last thing! Add a profile picture</span>
</div>
<form onSubmit={handleSubmit(changeOnClick)} encType="multipart/form-data" >
<div>
<span className="dot"></span>
<input onChange={e => setUserImage(e.target.value)} ref = {register} type='file' name='userImage' className='picUploader'/>
{/* <button>submit</button> */}
</div>
<div>
<button type='submit' className='doneButton'>Done</button>
<div>
<span className='laterTwo'>I'll do this later</span>
</div>
</div>
</form>
</Modal>
)
}
export default ProfilePicture;
import React,{useState,useContext}来自“React”;
从“../cancel.svg”导入退出;
从“反应模态”导入模态;
从“react hook form”导入{useForm};
从“axios”导入axios;
从“./context/UserContext”导入UserContext;
从“react router dom”导入{useHistory};
Modal.setAppElement(“#根”);
const ProfilePicture=()=>{
const[modalIsOpen,setModalIsOpen]=使用状态(true);
常量{register,handleSubmit}=useForm();
const[userImage,setUserImage]=useState();
const onSubmit=(数据)=>console.log(数据);
const{userData}=useContext(UserContext);
const history=useHistory();
const changeOnClick=e=>{
常量用户={
用户映像
};
console.log(用户);
axios
.放(`http://localhost:5000/users/update/${userData.user.id}`,用户)
.then(res=>console.log(res.body))
.catch(错误=>{
控制台日志(err);
});
历史。推送(“/着陆”)
}
返回(
setModalIsOpen(false)}className='finishBorder'>
最后一件事!添加个人资料图片
setUserImage(e.target.value)}ref={register}type='file'name='userImage'className='picUploader'/>
{/*提交*/}
多恩
我以后再做
)
}
导出默认配置文件图片;
感谢您的帮助!您从客户端发送的是一个“伪造路径”,而不是一个文件。要从输入访问该文件,请使用:
setUserImage(e.target.files[0])
此外,我认为multer只适用于多部分/表单数据,因此您应该检查这一点,但它非常简单:
const formData = new FormData();
formData.append([image name], [image file]);
axios.post(`http://localhost:5000/users/update/${userData.user.id}`, formData, {
headers: { "Content-Type": "multipart/form-data" }})
谢谢你,加斯顿!你的回答让我走上了正确的道路;我正在上面输入正确的工作代码