在Linux環境下使用Node.js實現文件的上傳和下載功能,通常會借助一些流行的框架和中間件。以下是使用Express.js框架結合Multer(用于上傳)和Express.static(用于下載)來實現這一功能的詳細步驟。
首先,確保你的Linux系統上已經安裝了Node.js和npm。你可以通過以下命令檢查是否已安裝:
node -v
npm -v
如果未安裝,可以訪問Node.js官網下載并安裝適合你系統的版本。
創建一個新的項目目錄并進入:
mkdir file-upload-download
cd file-upload-download
初始化一個新的Node.js項目:
npm init -y
安裝Express.js和Multer:
npm install express multer
創建一個名為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
運行。
修改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}`));
http://localhost:3000/upload
。file
,類型為File的字段,并選擇要上傳的文件。如果上傳成功,你將收到類似以下的響應:
{
"message": "File uploaded!",
"file": "uploads/1697052345678-image.jpg"
}
http://localhost:3000/download/1697052345678-image.jpg
(將文件名替換為你實際上傳的文件名)。在實際應用中,需要注意以下幾點以確保文件上傳和下載的安全性:
以下是完整的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}`));
通過以上步驟,你可以在Linux環境下使用Node.js和Express.js實現文件的上傳和下載功能。根據實際需求,你可以進一步擴展功能,例如添加用戶認證、文件列表展示、刪除文件等。同時,務必注意安全性,確保應用在生產環境中的穩定和安全運行。