Cómo cargar, mostrar y guardar imágenes usando node.js y express [cerrado]

104

Necesito cargar una imagen y mostrarla, así como guardarla para no perderla cuando actualice el localhost. Esto debe hacerse usando un botón "Cargar", que solicita una selección de archivo.

Estoy usando node.js y express para el código del lado del servidor.

usuario1602123
fuente
4
Eche un vistazo a FAQpara saber qué tipo de preguntas se deben hacer aquí. De todos modos, responderé a tu pregunta esta vez.
fardjad
103 usuarios no creen que esta pregunta sea ambigua, vaga, incompleta, demasiado amplia o retórica. Interesante. ;)
Andreas

Respuestas:

228

En primer lugar, debe crear un formulario HTML que contenga un elemento de entrada de archivo . También debe establecer el atributo enctype del formulario en multipart / form-data :

<form method="post" enctype="multipart/form-data" action="/upload">
    <input type="file" name="file">
    <input type="submit" value="Submit">
</form>

Suponiendo que el formulario está definido en index.html almacenado en un directorio llamado público en relación con el lugar donde se encuentra su script, puede servirlo de esta manera:

const http = require("http");
const path = require("path");
const fs = require("fs");

const express = require("express");

const app = express();
const httpServer = http.createServer(app);

const PORT = process.env.PORT || 3000;

httpServer.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});

// put the HTML file containing your form in a directory named "public" (relative to where this script is located)
app.get("/", express.static(path.join(__dirname, "./public")));

Una vez hecho esto, los usuarios podrán cargar archivos a su servidor a través de ese formulario. Pero para volver a ensamblar el archivo cargado en su aplicación, deberá analizar el cuerpo de la solicitud (como datos de formulario de varias partes).

En Express 3.x , podría usar express.bodyParsermiddleware para manejar formularios de varias partes, pero a partir de Express 4.x , no hay un analizador de cuerpo incluido con el marco. Afortunadamente, puede elegir entre uno de los muchos analizadores de datos de formularios / multiparte disponibles . Aquí, usaré multer :

Necesita definir una ruta para manejar las publicaciones del formulario:

const multer = require("multer");

const handleError = (err, res) => {
  res
    .status(500)
    .contentType("text/plain")
    .end("Oops! Something went wrong!");
};

const upload = multer({
  dest: "/path/to/temporary/directory/to/store/uploaded/files"
  // you might also want to set some limits: https://github.com/expressjs/multer#limits
});


app.post(
  "/upload",
  upload.single("file" /* name attribute of <file> element in your form */),
  (req, res) => {
    const tempPath = req.file.path;
    const targetPath = path.join(__dirname, "./uploads/image.png");

    if (path.extname(req.file.originalname).toLowerCase() === ".png") {
      fs.rename(tempPath, targetPath, err => {
        if (err) return handleError(err, res);

        res
          .status(200)
          .contentType("text/plain")
          .end("File uploaded!");
      });
    } else {
      fs.unlink(tempPath, err => {
        if (err) return handleError(err, res);

        res
          .status(403)
          .contentType("text/plain")
          .end("Only .png files are allowed!");
      });
    }
  }
);

En el ejemplo anterior, los archivos .png publicados en / subidos se guardarán en subidos directorio relación con el lugar donde se encuentra el script.

Para mostrar la imagen cargada, asumiendo que ya tiene una página HTML que contiene un elemento img :

<img src="/image.png" />

puede definir otra ruta en su aplicación exprés y usarla res.sendFilepara servir la imagen almacenada:

app.get("/image.png", (req, res) => {
  res.sendFile(path.join(__dirname, "./uploads/image.png"));
});
Fardjad
fuente
92
Usted señor es un caballero y un erudito
mattdlockyer
9
Para cualquiera que busque acceder a 'req.files' o 'req.body', body-parser ahora solo maneja JSON, visite github.com/expressjs/multer
Scott Meyers
5
como "app.use (express.bodyParser ({uploadDir: '...'}));" ya no funciona, se debe usar "app.use (bodyParser ({uploadDir: '...'}));". por lo tanto, el analizador corporal debe agregarse a través de npm y agregarse al archivo en el que lo usa a través de "var bodyParser = require ('body-parser');"
Niklas Zantner
4
¿Cómo podemos hacer esto en Express 4?
Muhammad Shahzad
4
@fardjad ¿Qué pasa si tengo angulares en el medio?
Gaurav51289