Postman funciona bien con mi código de backend. Usé form-data y puse un archivo aleatorio. Se cargó correctamente en la carpeta de imágenes, pero cuando se trata de React , no se está cargando, muestra un error en el backend y dice que el nombre del archivo no está definido. no entiendo el error
Creo que mi código frontal no funciona. Soy nuevo en esto. Aquí está mi código:
function Regstudent () { const [errorMessage, setErrorMessage] = useState("") let navigate = useNavigate(); async function handleRegister(e) { e.preventDefault() const form = e.target const user = { email: form[0].value, name: form[1].value, gender: form[2].value, password: form[3].value, batch: form[4].value, image:form[5].files } try { const res = await fetch("http://localhost:8000/api/studentregister", { method: "POST", headers: { "Content-type": "application/json" }, body: JSON.stringify(user) }) const data = await res.json() setErrorMessage(data.message) } catch (err) { setErrorMessage(err) } } <form encType='multipart/form-data' onSubmit={(e) => handleRegister(e)}> <input placeholder='Mail Address' className='umail' type="email" name="email" id="email" required /> <br /> <input placeholder='Full Name' className='fname' type="text" name="name" id="name" required /> <br /> <input placeholder='Gender' className='gender' type="text" name="gender" id="gender" required/> <br /> <input placeholder='Password' className='password' name="password" type="password" required/> <br /> <select name="batch" type="select" required> <option value="FSD">FSD</option> <option value="CEH">CEH</option> <option value="AI">AI</option> </select> <br /> <input type="file" accept=".png, .jpg, .jpeg" name="image" /> <br /> <input type="submit" className='regbutton' value="Register" /> </Form>BACK END (Express con Multer):
//multer & uuid const storage = multer.diskStorage({ destination: function(req, file, cb) { cb(null, 'images'); }, filename: function(req, file, cb) { cb(null, uuidv4() + '-' + Date.now() + path.extname(file.originalname)); } }); const fileFilter = (req, file, cb) => { const allowedFileTypes = ['image/jpeg', 'image/jpg', 'image/png']; if(allowedFileTypes.includes(file.mimetype)) { cb(null, true); } else { cb(null, false); } } let upload = multer({ storage, fileFilter }); //POST app.post("/api/studentregister", upload.single('image'), async(req,res)=>{ const user = req.body; //check user name or pswd is taken before const takenEmail = await Users.findOne({email: user.email}) const regex = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i; if (takenEmail){ res.json ({message: "Email has already been taken"}) }else if(!regex.test(user.email)) { res.json ({message:"Email is invalid"}); } else{ user.password = await bcrypt.hash(req.body.password, 10) const dbUser = new Users({ email: user.email.toLowerCase(), name: user.name, gender:user.gender, password: user.password, batch:user.batch, image: req.file.filename, role: "user" }) dbUser.save() res.json({message: "Success"}) } })Una manera fácil de enviar archivos con fetch es usar el objeto FormData , que permite enviar multipart/form-data . Al igual que :
async function handleRegister(e) { e.preventDefault() const formData = new FormData(e.target); try { const res = await fetch("http://localhost:8000/api/studentregister", { method: "POST", body: formData }) const data = await res.json() setErrorMessage(data.message) } catch (err) { setErrorMessage(err) } }