Cómo cargar archivos en el servidor usando Fetch API

La carga de archivos es una de las características más comunes en una aplicación web hoy en día. Hay muchas bibliotecas de JavaScript disponibles que manejan la carga de archivos como una brisa.

Pero no carguemos una biblioteca completa solo para esta característica única que se puede manejar fácilmente en JavaScript nativo usando Fetch API. Fetch es un reemplazo moderno basado en promesas de XHR para realizar solicitudes HTTP en el navegador.

Obtener carga de archivos

Agreguemos el siguiente elemento de entrada HTML a su sitio web:

<input type="file" id="avatar">

Ahora agregue un detector de eventos en la entrada que se activará cuando el usuario elija un archivo:

// select file input
const input = document.getElementById('avatar');

// add event listener
input.addEventListener('change', () => {
    uploadFile(input.files[0]);
});

A continuación, agregue uploadFile() método que recibe un File objeto como entrada y lo carga en el servidor con fetch() utilizando la interfaz FormData:

const uploadFile = (file) => {

    // add file to FormData object
    const fd = new FormData();
    fd.append('avatar', file);

    // send `POST` request
    fetch('/upload-avatar', {
        method: 'POST',
        body: fd
    })
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error(err));
}

Validar tipo y tamaño de archivo

También puede validar las propiedades (como el tipo de archivo y el tamaño del archivo) del archivo antes de comenzar a cargarlo en el servidor:

const uploadFile = (file) => {

    // check file type
    if(!['image/jpeg', 'image/gif', 'image/png', 'image/svg+xml'].includes(file.type)) {
        console.log('Only images are allowed.');
        return;
    }

    // check file size (< 2MB)
    if(file.size > 2 * 1024 * 1024) {
        console.log('File must be less than 2MB.');
        return;
    }

    // ...
}

Manejo de la carga de archivos en el lado del servidor usando Node.js

Aquí hay un código de ejemplo que maneja la solicitud de carga de archivos anterior en Node.js. estoy usando express-fileupload — un middleware Express simple para cargar archivos. Analiza multipart/form-data requests , extrae los archivos si están disponibles y los pone a disposición en req.files propiedad:

app.post('/upload-avatar', async (req, res) => {
    try {
        if(!req.files) {
            res.send({
                status: false,
                message: 'No file uploaded'
            });
        } else {
            //Use the name of the input field (i.e. "avatar") to retrieve the uploaded file
            let avatar = req.files.avatar;
            
            //Use the mv() method to place the file in upload directory (i.e. "uploads")
            avatar.mv('./uploads/' + avatar.name);

            //send response
            res.send({
                status: true,
                message: 'File is uploaded',
                data: {
                    name: avatar.name,
                    mimetype: avatar.mimetype,
                    size: avatar.size
                }
            });
        }
    } catch (err) {
        res.status(500).send(err);
    }
});

Manejo de la carga de archivos en el lado del servidor usando Spring Boot

Si planea usar Spring Boot para el back-end, aquí hay un fragmento de código de ejemplo que procesa la solicitud de carga de archivos anterior en Spring Boot:

@PostMapping("/upload-avatar")
@ResponseBody
public ResponseEntity<String> fileUpload(MultipartFile avatar) {
    try {

        // upload directory - change it to your own
        String UPLOAD_DIR = "/opt/uploads";

        // create a path from file name
        Path path = Paths.get(UPLOAD_DIR, avatar.getOriginalFilename());

        // save the file to `UPLOAD_DIR`
        // make sure you have permission to write
        Files.write(path, avatar.getBytes());
    }
    catch (Exception ex) {
        ex.printStackTrace();
        return new ResponseEntity<>("Invalid file format!!", HttpStatus.BAD_REQUEST);
    }

    return new ResponseEntity<>("File uploaded!!", HttpStatus.OK);
}