如何使用node.js上载,显示和保存图像并表达


104

我需要上传,显示并保存图像,以免刷新本地主机时不会丢失它。这需要使用“上传”按钮来完成,该按钮提示选择文件。

我正在使用node.js并表示服务器端代码。


4
看看,FAQ以了解在这里应该问什么样的问题。无论如何,这次我会回答你的问题。
fardjad 2013年

103位用户认为此问题不是模棱两可,含糊,不完整,过于宽泛或夸张。有趣。;)
Andreas

Answers:


229

首先,您应该制作一个包含文件input元素的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!");
      });
    }
  }
);

在上面的示例中,发布到/ upload的.png文件将保存到相对于脚本所在位置的上目录。

为了显示上传的图像,假设您已经有一个包含img元素的HTML页面:

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

您可以在快速应用中定义另一条路线,并用于res.sendFile投放存储的图像:

app.get("/image.png", (req, res) => {
  res.sendFile(path.join(__dirname, "./uploads/image.png"));
});

93
您的先生
既是

9
对于希望访问“ req.files”或“ req.body”的任何人,body-parser现在仅处理JSON,请访问github.com/expressjs/multer
Scott Meyers

5
作为“ app.use(express.bodyParser({uploadDir:'...'})));” 不再工作,应该使用“ app.use(bodyParser({uploadDir:'...'}));;”。因此,必须通过npm添加body-parser,然后通过“ var bodyParser = require('body-parser');”将其添加到使用它的文件中。
Niklas Zantner 2015年

4
我们如何在Express 4中做到这一点?
穆罕默德·沙扎德

4
@fardjad如果我之间有角度怎么办?
Gaurav51289 '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.