es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Multer devuelve “indefinido” al cargar archivos de imagen en formato svg.

Quiero subir una imagen SVG a mi servidor NodeJs – Express desde React (usando Redux). Estoy utilizando el módulo npm signature_pad para dibujar firmas.
Este es el código en React:

formData.append(‘contractId’, contractId);
formData.append(‘svg_signature’,signaturePad.toDataURL(“image/svg+xml”));

dispatch(sign_contract_action(formData));

Esto es cómo se ve signaturePad.toDataURL(“image/svg+xml”):

data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDov…

Este es mi enrutador Express:

router.post(‘/sign-contract’,upload_file.single(‘svg_signature’),save_svg_signature);

Y esta es la parte donde quiero recibir el archivo de imagen SVG y almacenarlo, pero es indefinido:

const save_svg_signature = async (req,res,next) => {
const { file } = req;
const { contractId } = req.body;
console.log(contractId); // funciona
console.log(file); // indefinido
};

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para subir una imagen SVG de React a NodeJs-Express usando multer, debes modificar tu código de React para crear un objeto FormData que incluya el archivo de imagen que se va a subir al servidor.

    El método signaturePad.toDataURL("image/svg+xml") devuelve una cadena codificada en base64 de la imagen SVG, la cual luego se puede convertir en un objeto de archivo usando new File().

    A continuación se muestra un ejemplo de cómo puedes modificar tu código para lograr esto:

    // Convertir la imagen SVG codificada en base64 a un objeto de archivo
    const dataURItoFile = (dataURI) => {
      const byteString = atob(dataURI.split(',')[1]);
      const ab = new ArrayBuffer(byteString.length);
      const ia = new Uint8Array(ab);
      for (let i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
      }
      const file = new File([ia], 'signature.svg', {type: 'image/svg+xml'});
      return file;
    }
    
    // Crear un objeto FormData con el contratoId y el archivo de imagen
    const formData = new FormData();
    formData.append('contractId', contractId);
    formData.append('svg_signature', dataURItoFile(signaturePad.toDataURL("image/svg+xml")));
    
    // Enviar los datos del formulario al servidor usando Redux
    dispatch(sign_contract_action(formData));
    

    Ahora en tu código de servidor, puedes usar multer para manejar la subida de archivos y guardar el archivo en el directorio deseado.

    El objeto de archivo se puede acceder a través de la propiedad req.file, y los otros campos de datos del formulario se pueden acceder a través de la propiedad req.body.

    Aquí tienes una versión actualizada de tu código de servidor:

    // Importar multer
    const multer = require('multer');
    
    // Configurar el almacenamiento de multer
    const storage = multer.diskStorage({
      destination: function (req, file, cb) {
        cb(null, 'ruta/a/tu/directorio') // Establece tu directorio deseado aquí
      },
      filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
      }
    })
    
    // Configurar la instancia de multer para subir archivos
    const upload = multer({ storage: storage })
    
    // Configurar tu ruta con el middleware de multer
    router.post('/sign-contract', upload.single('svg_signature'), save_svg_signature);
    
    // Manejar la subida de archivos y los datos del formulario
    const save_svg_signature = async (req, res, next) => {
      const { file } = req;
      const { contractId } = req.body;
      console.log(contractId); // ¡Funciona!
      console.log(file); // Devuelve el objeto de archivo con tamaño, tipo de contenido, etc.
    };
    

    Asegúrate de probar cuidadosamente tu código para asegurarte de que todo funcione como se espera.

Comments are closed.