随着互联网的发展,文件上传和下载已经成为了我们日常工作中不可或缺的一部分。在前端开发中,我们常常需要实现文件上传和下载的功能。本文将介绍如何使用 Node.js 实现文件上传和下载的完整教程,包括详细的代码和操作步骤。
文件上传
1. 创建上传表单
首先,我们需要在前端页面中创建一个上传表单,让用户可以选择需要上传的文件。可以使用 form
标签和 input
标签来实现:
<form action="/upload" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="上传"> </form>
其中 action
属性指定了上传文件的地址,method
属性指定了请求的方式为 post
,enctype
属性指定了表单数据的编码类型为 multipart/form-data
,这是文件上传时必须设置的。
2. 处理上传请求
当用户点击上传按钮后,前端会向后端发送一个上传请求。在 Node.js 中,我们可以使用 multer
中间件来处理上传请求,代码如下:
// javascriptcn.com 代码示例 const express = require('express'); const multer = require('multer'); const app = express(); const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/'); }, filename: function (req, file, cb) { cb(null, file.originalname); } }); const upload = multer({ storage: storage }); app.post('/upload', upload.single('file'), function (req, res) { res.send('上传成功'); }); app.listen(3000, function () { console.log('Server is running on port 3000'); });
上面的代码中,我们使用 multer
中间件来处理上传请求,首先定义了一个存储引擎 storage
,指定了上传文件的存储路径和文件名。然后,我们使用 multer({ storage: storage })
来创建一个 upload
中间件,用于处理上传请求。最后,我们使用 upload.single('file')
来处理上传的单个文件,并在回调函数中返回上传成功的消息。
3. 完善文件上传
上面的代码只是实现了最基本的文件上传功能,还有一些需要注意的细节:
- 为了防止上传文件大小超出限制,我们可以使用
limits
选项来设置文件大小限制。 - 为了防止上传文件类型不符合要求,我们可以使用
fileFilter
选项来设置文件类型过滤器。 - 为了方便管理上传的文件,我们可以使用
uuid
生成一个唯一的文件名,并将文件名保存在数据库中。
下面是完善后的文件上传代码:
// javascriptcn.com 代码示例 const express = require('express'); const multer = require('multer'); const uuid = require('uuid'); const app = express(); const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/'); }, filename: function (req, file, cb) { const filename = uuid.v4() + '-' + file.originalname; cb(null, filename); } }); const upload = multer({ storage: storage, limits: { fileSize: 1024 * 1024 * 10 // 限制文件大小为 10MB }, fileFilter: function (req, file, cb) { const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']; if (!allowedTypes.includes(file.mimetype)) { const error = new Error('文件类型不符合要求'); error.code = 'LIMIT_FILE_TYPES'; return cb(error, false); } cb(null, true); } }); app.post('/upload', upload.single('file'), function (req, res) { res.send('上传成功'); }); app.listen(3000, function () { console.log('Server is running on port 3000'); });
文件下载
1. 创建下载链接
在前端页面中,我们可以使用 a
标签来创建一个下载链接,代码如下:
<a href="/download?filename=test.jpg">下载</a>
其中 href
属性指定了下载文件的地址,filename
参数指定了要下载的文件名。
2. 处理下载请求
当用户点击下载链接时,前端会向后端发送一个下载请求。在 Node.js 中,我们可以使用 express
框架来处理下载请求,代码如下:
// javascriptcn.com 代码示例 const express = require('express'); const fs = require('fs'); const app = express(); app.get('/download', function (req, res) { const filename = req.query.filename; const filepath = 'uploads/' + filename; const filestream = fs.createReadStream(filepath); filestream.pipe(res); }); app.listen(3000, function () { console.log('Server is running on port 3000'); });
上面的代码中,我们使用 fs
模块来读取下载文件,并使用 createReadStream
方法创建一个可读流。然后,我们使用 pipe
方法将可读流输出到响应对象中,实现文件的下载。
3. 完善文件下载
上面的代码只是实现了最基本的文件下载功能,还有一些需要注意的细节:
- 为了防止下载文件不存在,我们可以使用
fs.existsSync
方法来判断文件是否存在。 - 为了防止下载文件被恶意访问,我们可以使用
Content-Disposition
头来指定下载文件的名称和类型。 - 为了方便管理下载的文件,我们可以使用
uuid
生成一个唯一的文件名,并将文件名保存在数据库中。
下面是完善后的文件下载代码:
// javascriptcn.com 代码示例 const express = require('express'); const fs = require('fs'); const uuid = require('uuid'); const app = express(); app.get('/download', function (req, res) { const filename = req.query.filename; const filepath = 'uploads/' + filename; if (!fs.existsSync(filepath)) { res.status(404).send('文件不存在'); return; } const stats = fs.statSync(filepath); const filestream = fs.createReadStream(filepath); res.setHeader('Content-Type', 'application/octet-stream'); res.setHeader('Content-Disposition', 'attachment; filename=' + uuid.v4() + '-' + filename); res.setHeader('Content-Length', stats.size); filestream.pipe(res); }); app.listen(3000, function () { console.log('Server is running on port 3000'); });
总结
本文介绍了如何使用 Node.js 实现文件上传和下载的完整教程,包括创建上传表单、处理上传请求、创建下载链接、处理下载请求等步骤。同时,我们还介绍了一些需要注意的细节,如文件大小限制、文件类型过滤器、文件名生成、文件不存在处理、文件下载头等内容。希望本文对你有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/656fd1afd2f5e1655d837733