Как загружать, отображать и сохранять изображения с помощью node.js и Express [закрыто]

104

Мне нужно загрузить изображение и отобразить его, а также сохранить, чтобы я не потерял его при обновлении localhost. Это необходимо сделать с помощью кнопки «Загрузить», которая запрашивает выбор файла.

Я использую node.js и выражаю код на стороне сервера.

user1602123
источник
4
Взгляните на, FAQчтобы узнать, какие вопросы следует здесь задавать. В любом случае, на этот раз я отвечу на ваш вопрос.
fardjad 02
103 пользователя не считают этот вопрос двусмысленным, расплывчатым, неполным, слишком широким или риторическим. Интересный. ;)
Андреас

Ответы:

230

Прежде всего, вы должны создать HTML-форму, содержащую элемент ввода файла . Вам также необходимо установить для атрибута enctype формы значение multipart / form-data :

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

Предполагая, что форма определена в index.html, хранящемся в каталоге с именем public относительно того, где расположен ваш скрипт, вы можете обслуживать его следующим образом:

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

Как только это будет сделано, пользователи смогут загружать файлы на ваш сервер через эту форму. Но для повторной сборки загруженного файла в вашем приложении вам необходимо проанализировать тело запроса (как данные многостраничной формы).

В Express 3.x вы можете использовать express.bodyParserпромежуточное ПО для обработки составных форм, но в Express 4.x нет синтаксического анализатора тела, связанного с фреймворком. К счастью, вы можете выбрать один из множества доступных парсеров multipart / form-data . Здесь я буду использовать multer :

Вам необходимо определить маршрут для обработки сообщений формы:

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

В приведенном выше примере файлы .png, отправленные в / upload, будут сохранены в загруженном каталоге относительно того, где расположен скрипт.

Чтобы показать загруженное изображение, если у вас уже есть HTML-страница, содержащая элемент img :

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

вы можете определить другой маршрут в своем экспресс-приложении и использовать его res.sendFileдля обслуживания сохраненного изображения:

app.get("/image.png", (req, res) => {
  res.sendFile(path.join(__dirname, "./uploads/image.png"));
});
фарджад
источник
94
Вы, сэр, джентльмен и ученый
Mattdlockyer
9
Для всех, кто хочет получить доступ к 'req.files' или 'req.body', body-parser теперь обрабатывает только JSON, проверьте github.com/expressjs/multer
Скотт Мейерс
5
как "app.use (express.bodyParser ({uploadDir: '...'}));" больше не работает, следует использовать "app.use (bodyParser ({uploadDir: '...'}));". поэтому body-parser должен быть добавлен через npm и добавлен в файл, в котором вы его используете, через "var bodyParser = require ('body-parser');"
Никлас Зантнер,
4
как мы можем сделать это в экспрессе 4?
Мухаммад Шахзад,
4
@fardjad Что делать, если у меня есть angular между ними?
Gaurav51289,