Express.js 是 Node.js 中一种流行的 Web 应用程序框架,它提供了许多有用的中间件和函数,帮助我们更方便地构建 Web 应用程序。在本文中,我将介绍如何使用 Express.js 来实现文件下载和断点续传功能。
为什么需要文件下载和断点续传功能
文件下载是 Web 应用程序中常见的一种功能,用户可以通过浏览器下载服务器上的文件。然而,如果要下载的文件体积较大,或者用户的网络连接速度较慢,下载过程可能会非常耗时,甚至中途失败。此时,如果重新开始下载,之前已经下载过的文件也需要重新下载,这无疑浪费了带宽和时间。
为了解决这个问题,我们可以使用断点续传功能。断点续传意味着在下载中途失败后,用户可以从下载中断的位置继续下载,而不需要重新下载整个文件。这大大提高了下载效率,也减少了网络带宽的浪费。
实现文件下载
在 Express.js 中实现文件下载非常简单。我们可以使用 res.download()
函数来向用户发送文件。例如:
app.get('/download', function(req, res) { res.download('/path/to/file'); });
如果要指定下载时展示的文件名,可以使用第二个参数。例如:
app.get('/download', function(req, res) { res.download('/path/to/file', 'new-filename.txt'); });
上述代码将会下载 /path/to/file
文件,并将其保存为 new-filename.txt
。
实现断点续传
要实现断点续传,我们需要首先在 HTTP 响应头中添加 Content-Range
和 Content-Length
属性,指定下载的数据范围和总体积。同时,为了通知浏览器可以断点续传,还需要在响应头中添加 Accept-Ranges
和 Content-Disposition
属性。
下面是一个示例代码,实现将文件读取并以流的方式输出到响应中:
// javascriptcn.com 代码示例 app.get('/download/:filename', function(req, res) { let filename = req.params.filename; let filepath = path.join(__dirname, 'files', filename); let stats = fs.statSync(filepath); let start = 0; let end = stats.size - 1; let range = req.headers.range; if (range) { let parts = range.replace(/bytes=/, '').split('-'); let newStart = parts[0]; let newEnd = parts[1] ? parseInt(parts[1], 10) : end; start = parseInt(newStart, 10); end = newEnd; let chunksize = (end - start) + 1; let stream = fs.createReadStream(filepath, { start, end }); res.writeHead(206, { 'Content-Range': 'bytes ' + start + '-' + end + '/' + stats.size, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment;filename=' + filename }); stream.pipe(res); } else { res.writeHead(200, { 'Content-Length': stats.size, 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment;filename=' + filename }); fs.createReadStream(filepath).pipe(res); } });
上述代码中,我们首先获取要下载的文件路径和大小。如果请求中包含了 range
头部,说明该请求是断点续传请求,我们需要根据该头部指定下载的数据范围和总体积,并使用 fs.createReadStream()
方法创建流并输出到响应中。否则,说明该请求是新的下载请求,我们直接使用 fs.createReadStream()
将文件输出到响应中。
示例代码中还定义了响应头部各个属性的值,包括:
206 Partial Content
:表示该响应中包含了部分数据。Content-Range
:指定要下载的数据范围。Accept-Ranges
:通知浏览器服务器支持断点续传。Content-Length
:指定要下载的数据大小。Content-Type
:指定下载数据的格式。Content-Disposition
:指定要下载的文件名和下载方式。
完成上述步骤后,我们的文件下载和断点续传功能就可以正常工作了。
总结
本文介绍了如何在 Express.js 中实现文件下载和断点续传功能。下载功能的实现非常简单,只需要使用 res.download()
函数即可。而断点续传功能则需要添加一些额外的 HTTP 响应头和判断逻辑。通过本文的学习和示例代码的实现,相信读者可以快速掌握如何在 Express.js 中实现这两个功能,并将其应用到自己的 Web 应用程序中。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654072e37d4982a6eb9f413c