Como fazer upload, exibir e salvar imagens usando node.js e express [fechado]

104

Preciso fazer o upload de uma imagem e exibi-la, bem como salvá-la para não perdê-la quando atualizar o localhost. Isso precisa ser feito usando um botão "Upload", que solicita uma seleção de arquivo.

Estou usando node.js e express para o código do lado do servidor.

user1602123
fonte
4
Dê uma olhada em FAQpara saber que tipo de perguntas devem ser feitas aqui. De qualquer forma, responderei sua pergunta desta vez.
fardjad
103 usuários não acham que esta pergunta seja ambígua, vaga, incompleta, excessivamente ampla ou retórica. Interessante. ;)
Andreas

Respostas:

228

Em primeiro lugar, você deve fazer um formulário HTML contendo um elemento de entrada de arquivo . Você também precisa definir o atributo enctype do formulário como multipart / form-data :

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

Supondo que o formulário esteja definido em index.html armazenado em um diretório denominado public relativo ao local onde seu script está localizado, você pode exibi-lo desta forma:

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")));

Depois de fazer isso, os usuários poderão fazer upload de arquivos para o seu servidor por meio desse formulário. Mas, para remontar o arquivo carregado em seu aplicativo, você precisará analisar o corpo da solicitação (como dados de formulário de várias partes).

No Express 3.x, você poderia usar express.bodyParsermiddleware para lidar com formulários de várias partes, mas a partir do Express 4.x , não há analisador de corpo empacotado com a estrutura. Felizmente, você pode escolher um dos muitos analisadores multipart / form-data disponíveis . Aqui, vou usar o multer :

Você precisa definir uma rota para lidar com as postagens do formulário:

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!");
      });
    }
  }
);

No exemplo acima, os arquivos .png postados em / upload serão salvos no diretório carregado em relação ao local onde o script está localizado.

Para mostrar a imagem enviada, supondo que você já tenha uma página HTML contendo um elemento img :

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

você pode definir outra rota em seu aplicativo expresso e usar res.sendFilepara servir a imagem armazenada:

app.get("/image.png", (req, res) => {
  res.sendFile(path.join(__dirname, "./uploads/image.png"));
});
Fardjad
fonte
92
O senhor é um cavalheiro e um estudioso
mattdlockyer
9
Para quem deseja acessar 'req.files' ou 'req.body', o analisador de corpo agora só lida com JSON, verifique github.com/expressjs/multer
Scott Meyers
5
como "app.use (express.bodyParser ({uploadDir: '...'}));" não está mais funcionando, deve-se usar "app.use (bodyParser ({uploadDir: '...'}));". portanto, o body-parser deve ser adicionado via npm e adicionado ao arquivo em que você o está usando via "var bodyParser = require ('body-parser');"
Niklas Zantner
4
como podemos fazer isso no expresso 4?
Muhammad Shahzad,
4
@fardjad E se eu tiver angular no meio?
Gaurav51289