溫馨提示×

Linux Node.js如何實現文件上傳下載功能

小樊
57
2025-05-17 22:06:41
欄目: 編程語言

在Linux環境下使用Node.js實現文件的上傳和下載功能,通常會借助一些流行的框架和中間件。以下是使用Express.js框架結合Multer(用于上傳)和Express.static(用于下載)來實現這一功能的詳細步驟。

1. 環境準備

安裝Node.js和npm

首先,確保你的Linux系統上已經安裝了Node.js和npm。你可以通過以下命令檢查是否已安裝:

node -v
npm -v

如果未安裝,可以訪問Node.js官網下載并安裝適合你系統的版本。

創建項目目錄

創建一個新的項目目錄并進入:

mkdir file-upload-download
cd file-upload-download

初始化npm

初始化一個新的Node.js項目:

npm init -y

2. 安裝必要的依賴

安裝Express.js和Multer:

npm install express multer

3. 實現文件上傳功能

創建一個名為app.js的文件,并添加以下代碼:

const express = require('express');
const multer  = require('multer');
const path = require('path');

const app = express();

// 設置存儲引擎
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/') // 設置上傳文件的存儲目錄
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + '-' + file.originalname) // 重命名文件以避免沖突
  }
});

// 初始化上傳
const upload = multer({
  storage: storage,
  limits: { fileSize: 10 * 1024 * 1024 }, // 限制文件大小為10MB
  fileFilter: function (req, file, cb) {
    checkFileType(file, cb);
  }
}).single('file'); // 'file' 是表單中文件字段的名稱

// 檢查文件類型
function checkFileType(file, cb) {
  // 允許的擴展名
  const filetypes = /jpeg|jpg|png|gif/;
  // 檢查擴展名
  const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
  // 檢查MIME類型
  const mimetype = filetypes.test(file.mimetype);

  if (mimetype && extname) {
    return cb(null, true);
  } else {
    cb('Error: Images Only!');
  }
}

// 上傳路由
app.post('/upload', (req, res) => {
  upload(req, res, (err) => {
    if (err) {
      res.status(400).send({ message: err });
    } else {
      if (req.file == undefined) {
        res.status(400).send({ message: 'No file selected!' });
      } else {
        res.send({
          message: 'File uploaded!',
          file: `uploads/${req.file.filename}`
        });
      }
    }
  });
});

// 啟動服務器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

創建上傳目錄

在項目根目錄下創建一個uploads文件夾,用于存放上傳的文件:

mkdir uploads

運行服務器

啟動服務器:

node app.js

服務器將在http://localhost:3000運行。

4. 實現文件下載功能

修改app.js,添加下載路由:

// 下載路由
app.get('/download/:filename', (req, res) => {
  const { filename } = req.params;
  const filePath = path.join(__dirname, 'uploads', filename);

  // 檢查文件是否存在
  fs.access(filePath, fs.constants.F_OK, (err) => {
    if (err) {
      return res.status(404).send({ message: 'File not found!' });
    }
    res.download(filePath, filename, (err) => {
      if (err) throw err;
    });
  });
});

確保引入fs模塊:

const fs = require('fs');

完整代碼如下:

const express = require('express');
const multer  = require('multer');
const path = require('path');
const fs = require('fs');

const app = express();

// 設置存儲引擎
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/') // 設置上傳文件的存儲目錄
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + '-' + file.originalname) // 重命名文件以避免沖突
  }
});

// 初始化上傳
const upload = multer({
  storage: storage,
  limits: { fileSize: 10 * 1024 * 1024 }, // 限制文件大小為10MB
  fileFilter: function (req, file, cb) {
    checkFileType(file, cb);
  }
}).single('file'); // 'file' 是表單中文件字段的名稱

// 檢查文件類型
function checkFileType(file, cb) {
  // 允許的擴展名
  const filetypes = /jpeg|jpg|png|gif/;
  // 檢查擴展名
  const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
  // 檢查MIME類型
  const mimetype = filetypes.test(file.mimetype);

  if (mimetype && extname) {
    return cb(null, true);
  } else {
    cb('Error: Images Only!');
  }
}

// 上傳路由
app.post('/upload', (req, res) => {
  upload(req, res, (err) => {
    if (err) {
      res.status(400).send({ message: err });
    } else {
      if (req.file == undefined) {
        res.status(400).send({ message: 'No file selected!' });
      } else {
        res.send({
          message: 'File uploaded!',
          file: `uploads/${req.file.filename}`
        });
      }
    }
  });
});

// 下載路由
app.get('/download/:filename', (req, res) => {
  const { filename } = req.params;
  const filePath = path.join(__dirname, 'uploads', filename);

  // 檢查文件是否存在
  fs.access(filePath, fs.constants.F_OK, (err) => {
    if (err) {
      return res.status(404).send({ message: 'File not found!' });
    }
    res.download(filePath, filename, (err) => {
      if (err) throw err;
    });
  });
});

// 啟動服務器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

5. 測試文件上傳和下載

使用Postman測試上傳

  1. 打開Postman。
  2. 創建一個新的POST請求,URL為http://localhost:3000/upload。
  3. Body選項卡中,選擇form-data。
  4. 添加一個鍵為file,類型為File的字段,并選擇要上傳的文件。
  5. 點擊Send發送請求。

如果上傳成功,你將收到類似以下的響應:

{
  "message": "File uploaded!",
  "file": "uploads/1697052345678-image.jpg"
}

使用瀏覽器測試下載

  1. 訪問http://localhost:3000/download/1697052345678-image.jpg(將文件名替換為你實際上傳的文件名)。
  2. 瀏覽器將開始下載該文件。

6. 安全性考慮

在實際應用中,需要注意以下幾點以確保文件上傳和下載的安全性:

  1. 驗證用戶權限:確保只有授權用戶才能上傳和下載文件。
  2. 限制文件類型和大小:根據需求限制允許上傳的文件類型和大小,防止服務器資源被濫用。
  3. 防止路徑遍歷攻擊:在處理文件下載時,確保用戶無法通過修改URL訪問到不應該公開的文件。
  4. 存儲安全:將上傳的文件存儲在非Web根目錄下,避免直接通過瀏覽器訪問。
  5. 使用HTTPS:在生產環境中,使用HTTPS加密傳輸數據,保護數據安全。

7. 完整代碼示例

以下是完整的app.js代碼,整合了上傳和下載功能:

const express = require('express');
const multer  = require('multer');
const path = require('path');
const fs = require('fs');

const app = express();

// 設置存儲引擎
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/') // 設置上傳文件的存儲目錄
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + '-' + file.originalname) // 重命名文件以避免沖突
  }
});

// 初始化上傳
const upload = multer({
  storage: storage,
  limits: { fileSize: 10 * 1024 * 1024 }, // 限制文件大小為10MB
  fileFilter: function (req, file, cb) {
    checkFileType(file, cb);
  }
}).single('file'); // 'file' 是表單中文件字段的名稱

// 檢查文件類型
function checkFileType(file, cb) {
  // 允許的擴展名
  const filetypes = /jpeg|jpg|png|gif/;
  // 檢查擴展名
  const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
  // 檢查MIME類型
  const mimetype = filetypes.test(file.mimetype);

  if (mimetype && extname) {
    return cb(null, true);
  } else {
    cb('Error: Images Only!');
  }
}

// 上傳路由
app.post('/upload', (req, res) => {
  upload(req, res, (err) => {
    if (err) {
      res.status(400).send({ message: err });
    } else {
      if (req.file == undefined) {
        res.status(400).send({ message: 'No file selected!' });
      } else {
        res.send({
          message: 'File uploaded!',
          file: `uploads/${req.file.filename}`
        });
      }
    }
  });
});

// 下載路由
app.get('/download/:filename', (req, res) => {
  const { filename } = req.params;
  const filePath = path.join(__dirname, 'uploads', filename);

  // 檢查文件是否存在
  fs.access(filePath, fs.constants.F_OK, (err) => {
    if (err) {
      return res.status(404).send({ message: 'File not found!' });
    }
    res.download(filePath, filename, (err) => {
      if (err) throw err;
    });
  });
});

// 啟動服務器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

8. 總結

通過以上步驟,你可以在Linux環境下使用Node.js和Express.js實現文件的上傳和下載功能。根據實際需求,你可以進一步擴展功能,例如添加用戶認證、文件列表展示、刪除文件等。同時,務必注意安全性,確保應用在生產環境中的穩定和安全運行。

0
亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女