วิธีอัปโหลดแสดงและบันทึกภาพโดยใช้ node.js และ express [ปิด]


112

ฉันต้องการอัปโหลดภาพและแสดงรวมทั้งบันทึกเพื่อไม่ให้สูญหายเมื่อฉันรีเฟรช localhost ต้องทำโดยใช้ปุ่ม "อัปโหลด" ซึ่งจะแจ้งให้เลือกไฟล์

ฉันใช้ node.js และ Express สำหรับโค้ดฝั่งเซิร์ฟเวอร์


4
ดูFAQเพื่อทราบว่าคำถามประเภทใดที่ควรถามที่นี่ คราวนี้ฉันจะตอบคำถามของคุณ
fardjad

ผู้ใช้ 103 คนไม่คิดว่าคำถามนี้คลุมเครือคลุมเครือไม่สมบูรณ์กว้างเกินไปหรือมีวาทศิลป์ น่าสนใจ. ;)
Andreas

คำตอบ:


260

แรกของทั้งหมดที่คุณควรให้เป็นรูปแบบ 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 ข้อมูล parsers ออกมี ที่นี่ฉันจะใช้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 ที่โพสต์ไปยัง/ อัปโหลดจะถูกบันทึกลงในไดเร็กทอรีที่อัปโหลดโดยสัมพันธ์กับตำแหน่งของสคริปต์

ในการแสดงภาพที่อัปโหลดสมมติว่าคุณมีหน้า HTML ที่มีองค์ประกอบimg อยู่แล้ว :

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

คุณสามารถกำหนดเส้นทางอื่นในแอปด่วนของคุณและใช้res.sendFileเพื่อแสดงภาพที่จัดเก็บ:

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

105
คุณชายเป็นสุภาพบุรุษและเป็นนักวิชาการ
mattdlockyer

9
สำหรับใครก็ตามที่ต้องการเข้าถึง "req.files" หรือ "req.body" ตอนนี้ body-parser จัดการเฉพาะ JSON โปรดดูที่github.com/expressjs/multer
Scott Meyers

5
เป็น "app.use (express.bodyParser ({uploadDir: '... '}));" ใช้งานไม่ได้อีกต่อไปควรใช้ "app.use (bodyParser ({uploadDir: '... '}));" ด้วยเหตุนี้ body-parser จะต้องถูกเพิ่มผ่าน npm และเพิ่มลงในไฟล์ที่คุณใช้ผ่าน "var bodyParser = ต้องใช้ ('body-parser');"
Niklas Zantner

4
เราจะทำสิ่งนี้ใน Express 4 ได้อย่างไร?
Muhammad Shahzad

4
@fardjad จะเกิดอะไรขึ้นถ้าฉันมีเชิงมุมอยู่ระหว่าง?
Gaurav51289
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.