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.


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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.