Así que estoy trabajando con la carga de imágenes desde mi aplicación React donde el backend es Node y Express. En mi componente de reacción, tengo un formulario con un archivo de tipo de entrada y un botón de envío. Estoy tratando de cargar la imagen primero (para darle al usuario la opción de eliminar la imagen cargada) y luego enviar el formulario con el nombre del archivo que proviene de la respuesta de carga de la imagen. Pero en este momento obtengo un objeto vacío para req.body e indefinido para req.files en mi backend.
Este es mi componente React con controladores:
const ImageUpload = () => { const handleImageUpload = ( e, idx ) => { const formData = new FormData(); formData.append( 'image', e.target.files[ 0 ] ); dispatch( uploadImage( formData ) ); } const handleFormSubmit= ( e ) => { e.preventDefault(); } return ( <form onSubmit={handleFormSubmit} > <input type="file" accept=".jpg,.jpeg,.png,.gif" onChange={( e ) => handleImageUpload( e, idx )} /> <button type='submit'>Submit</button> </form> ) }Así es como se ve la acción de Redux:
export const uploadImage = ( imageData ) => async ( dispatch ) => { try { const config = { headers: { 'Content-Type': 'image/jpeg' } } const { data } = await axios.post( '/api/campaigns/upload-image', imageData, config ); dispatch({ type: UPLOAD_IMAGE_SUCCESS, payload: data }); } catch ( error ) { console.log(error) } }Así es como se ve el backend:
app.js const express = require( 'express' ); const PORT = process.env.PORT || 3001; const cors = require('cors'); const app = express(); app.use( express.urlencoded( { extended: true } ) ); app.use( express.json() ); app.options( "*", cors( { origin: 'http://localhost:3000', optionsSuccessStatus: 200 } ) ); app.use( cors( { origin: "http://localhost:3000", optionsSuccessStatus: 200 } ) ); router.js const uploadImage = asyncHandler( async ( req, res ) => { console.log( 'req.body: ', req.body ); // {} console.log( 'req.files: ', req.files ); // undefined } );¿Qué estoy haciendo mal aquí? ¿Es algo así como que formData solo funciona para envíos de formularios?
En la interfaz:
los encabezados deben ser
headers: { 'Content-Type': 'multipart/form-data', }En el back-end:
multer es una forma clásica de manejar la carga de archivos en ExpressJS.
var multer = require('multer'); var upload = multer({ dest: './uploads' })controlador o su servicio:
app.post('/upload', upload.single('image'), function (req, res) { console.log('body data:', req.body); console.log('files data:', req.files); res.sendStatus(200); });