我需要上传一张图片并进行显示,并保存它以便在刷新localhost时不会丢失它。这需要使用“上传”按钮来完成,该按钮会提示选择文件。
我正在使用node.js并表示服务器端代码。
答案 0 :(得分:159)
首先,您应该制作一个包含file input element的HTML表单。您还需要set the form's enctype attribute to 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(3000, () => {
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 开始,没有与之绑定的正文解析器框架。幸运的是,您可以从many available multipart/form-data parsers out there中选择一个。在这里,我将使用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"));
});