浅析Node.js实现HTTP文件下载


Posted in Javascript onAugust 05, 2016

前言

HTTP实现文件下载时,只要在服务器设置好相关响应头,并使用二进制传输文件数据即可,而客户端(浏览器)会根据响应头接收文件数据。而在Node.js中,设置好响应头后,读取文件流,再使用“.pipe()”方法将流转接到响应对象Response就可以实现一个简单的文件下载服务器。

1. 文件下载介绍

HTTP基于请求头和响应头实现状态交互,在得到服务器正确响应状态后,而客户端首先会解析响应头,并根据响应头来接收和展示数据(响应体)。对于文件下载来说,其实现过程如下:

    1.客户端发起文件资源请求

    2.服务器查找对应文件,并设置”Content-Type”、”Content-Disposition”等响应头,分别用于表示文件的”MIME”类型及文件描述

    3.客户端根据服务器返回的响应头解析和接收文件数据

需要设置的响应头

设置文件下载响应头时,除了常用的HTTP响应头外,比较重要是还要设置以下两个响应头:

Content-Type: application/octet-stream
Content-Disposition: attachment; filename=MyFileName.ext

在上面的设置中,”Content-Type: application/octet-stream”告诉浏览器这是一个二进制文件,”Content-Disposition”告诉浏览器这是一个需要下载的附件并告诉浏览器默认的文件名。如果不添加”Content-Disposition”响应头,浏览器可能会下载或显示文件内容,不同浏览器的处理有所不同。

2. Node.js文件下载服务器实现

接下来我们基于Express 框架实现一个简单文件下载服务器,在这个服务器中主要包括两个功能:服务器文件的浏览文件的下载

2.1 添加路由

创建Express应用后,添加如下两个路由:

router.get('/files', function(req, res, next) {
 // 显示服务器文件 
});
router.get('/file/:fileName', function(req, res, next) {
 // 实现文件下载 
});

上面的添加的两个路由分别用于:显示服务器文件、实现文件下载

2.2 显示服务器文件

实现服务器文件的显示,要通过”fs”模块读取文件目录并进行文件/目录检查等。还需要使用”path”模块处理文件路径。首先引入这两个模块:

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

显示服务器文件实现代码如下:

router.get('/files', function(req, res, next) {
 // 显示服务器文件 
 // 文件目录
 var filePath = path.join(__dirname, './');
 fs.readdir(filePath, function(err, results){
  if(err) throw err;
  if(results.length>0) {
   var files = [];
   results.forEach(function(file){
   if(fs.statSync(path.join(filePath, file)).isFile()){
     files.push(file);
   }
   })
   res.render('files', {files:files});
  } else {
   res.end('当前目录下没有文件');
  }
 });
});

上面代码中,读取目录后通过视图文件”files.ejs”显示可下载文件列表。其代码如下:

<!DOCTYPE html>
<html>
 <head>
  <title>下载文件选择</title>
 </head>
 <body>
  <h1>请选择下载文件:</h1>
  <% if(files.length>0) {%>
  <ul>
   <% files.forEach(function(file){ %>
   <li>
    <a href="/file/<%- file %>" target="_blank"><%- file %></a>
   </li>
   <%})%>
  </ul>
  <%} else {%>
  <p>没有可下载文件…</p>
  <%}%>
 </body>
</html>

2.3 实现文件下载

实现文件下载时,可以先读取文件到一个”Buffer”中,再通过”res.send()”或”res.end()”方法发送文件数据,也可以基于流(”Stream”)实现文件数据的发送。使用”Stream”实现文件下载时,可以使用”fs.createReadStream()”方法创建一个可读流,而响应对象Response是一个可写流。这样,只需要通过”.pipe()”方法将文件流转接到Response响应流中即可。

文件下载实现代码如下:

router.get('/file/:fileName', function(req, res, next) {
 // 实现文件下载 
 var fileName = req.params.fileName;
 var filePath = path.join(__dirname, fileName);
 var stats = fs.statSync(filePath); 
 if(stats.isFile()){
  res.set({
   'Content-Type': 'application/octet-stream',
   'Content-Disposition': 'attachment; filename='+fileName,
   'Content-Length': stats.size
  });
  fs.createReadStream(filePath).pipe(res);
 } else {
  res.end(404);
 }
});

总结

以上就是利用Node.js实现HTTP文件下载的全部内容,希望对大家学习Node.js有所帮助。

Javascript 相关文章推荐
禁止F5等快捷键的JS代码
Mar 06 Javascript
遍历jquery对象的代码分享
Nov 02 Javascript
jquery iframe操作详细解析
Nov 20 Javascript
jquery Ajax 实现加载数据前动画效果的示例代码
Feb 07 Javascript
jQuery之ajax删除详解
Feb 27 Javascript
解决自定义$(id)的方法与jquery选择器$冲突的问题
Jun 14 Javascript
jQuery简单实现提交数据出现loading进度条的方法
Mar 29 Javascript
JavaScript中创建对象的模式汇总
Apr 19 Javascript
JS中绑定事件顺序(事件冒泡与事件捕获区别)
Jan 24 Javascript
详解Angular.js指令中scope类型的几种特殊情况
Feb 21 Javascript
iview form清除校验状态的实现
Sep 19 Javascript
antd多选下拉框一行展示的实现方式
Oct 31 Javascript
JS中对Cookie的操作详解
Aug 05 #Javascript
jQuery插件EasyUI获取当前Tab中iframe窗体对象的方法
Aug 05 #Javascript
js实现精确到毫秒的倒计时效果
Aug 05 #Javascript
jQuery实现Select左右复制移动内容
Aug 05 #Javascript
jQuery插件EasyUI实现Layout框架页面中弹出窗体到最顶层效果(穿越iframe)
Aug 05 #Javascript
jQuery插件EasyUI设置datagrid的checkbox为禁用状态的方法
Aug 05 #Javascript
基于HTML+CSS+JS实现增加删除修改tab导航特效代码
Aug 05 #Javascript
You might like
全局记录程序片段的运行时间 正确找到程序逻辑耗时多的断点
2011/01/06 PHP
将PHP从5.3.28升级到5.3.29时Nginx出现502错误
2015/05/09 PHP
PHP模拟http请求的方法详解
2016/11/09 PHP
PHP实现随机生成水印图片功能
2017/03/22 PHP
详解php协程知识点
2018/09/21 PHP
php解压缩zip和rar压缩包文件的方法
2019/07/10 PHP
List the Stored Procedures in a SQL Server database
2007/06/20 Javascript
JS 实现导航栏悬停效果(续2)
2013/09/24 Javascript
jQuery实现的淡入淡出二级菜单效果代码
2015/09/15 Javascript
js格式化输入框内金额、银行卡号
2016/02/01 Javascript
Webpack 实现 AngularJS 的延迟加载
2016/03/02 Javascript
AngularJS入门教程之数据绑定用法示例
2016/11/01 Javascript
无循环 JavaScript(map、reduce、filter和find)
2017/04/08 Javascript
vue在手机中通过本机IP地址访问webApp的方法
2018/08/15 Javascript
Nuxt.js之自动路由原理的实现方法
2018/11/21 Javascript
vue实现全匹配搜索列表内容
2019/09/26 Javascript
Nuxt页面级缓存的实现
2020/03/09 Javascript
基于Python 的进程管理工具supervisor使用指南
2016/09/18 Python
Python3实现的字典遍历操作详解
2018/04/18 Python
对Python多线程读写文件加锁的实例详解
2019/01/14 Python
Django上使用数据可视化利器Bokeh解析
2019/07/31 Python
推荐8款常用的Python GUI图形界面开发框架
2020/02/23 Python
python GUI模拟实现计算器
2020/06/22 Python
德国旅游网站:weg.de
2018/06/03 全球购物
意大利一家专营包包和配饰的网上商店:Borse Last Minute
2019/08/26 全球购物
最新的大学生找工作自我评价
2013/09/29 职场文书
宿舍违规检讨书
2014/01/12 职场文书
安全责任书范文
2014/03/12 职场文书
化妆品活动策划方案
2014/05/23 职场文书
董事长助理工作职责范本
2014/07/01 职场文书
不遵守课堂纪律的检讨书
2014/09/24 职场文书
玩手机检讨书1000字
2014/10/20 职场文书
3.15消费者权益日活动总结
2015/02/09 职场文书
大学生支教感言
2015/08/01 职场文书
golang中字符串MD5生成方式总结
2021/07/04 Golang
Python 如何利用ffmpeg 处理视频素材
2021/11/27 Python