nodejs实现范围请求的实现代码


Posted in NodeJs onOctober 12, 2018

使服务器支持范围请求,允许客户端只请求文档的一部分。其流程是:

  1. 客户端向服务端发起请求
  2. 服务端响应,附上Accept-Ranges头(值表示表示范围的单位,通常是“bytes”),告诉客户端其接受范围请求
  3. 客户端发送新的请求,附上Ranges头,告诉服务端请求的是一个范围
  4. 服务端收到范围请求,分情况响应:
    1. 范围有效,服务端返回206 Partial Content,发送指定范围内内容,并在Content-Range头中指定该范围
    2. 范围无效,服务端返回416 Requested Range Not Satisfiable,并在Content-Range中指明可接受范围

请求中的Ranges头格式为(这里不考虑多范围请求了):

Ranges: bytes=[start]-[end]

其中 start 和 end 并不是必须同时具有:

  • 如果 end 省略,服务器应返回从 start 位置开始之后的所有字节
  • 如果 start 省略,end 值指的就是服务器该返回最后多少个字节
  • 如果均未省略,则服务器返回 start 和 end 之间的字节

响应中的Content-Range头有两种格式:

当范围有效返回 206 时:

Content-Range: bytes (start)-(end)/(total)

当范围无效返回 416 时:

Content-Range: bytes */(total)
//代码实现
res.setHeader('Content-Range', `bytes */${totalSize}`);

添加函数处理范围请求:

【注意】这里吧不合理的范围请求直接设置为返回全部,如果想设置范围错误就直接不返回可以设置http状态码为416

/**
 * 范围请求
 * 不在合理的范围内就直接返回所有
 * 在合理规范的范围内就按照返回对应的部分
 * @param {*} totleSize 总的范围
 * @param {*} req 
 * @param {*} res 
 */
module.exports = (totleSize, req, res) => {
  const range = req.headers['range'];
  if (!range) {
    return {code: 200};
  }
 
  const sizes = range.match(/bytes=(\d*)-(\d*)/);
  const end = sizes[2] || totleSize - 1;
  const start = sizes[1] || totleSize - end;
  //不规范的范围,是要直接一起返回,所以设置状态码200
  if(start > end || start < 0 || end > totleSize) {
    return {code: 200};
  }
  res.setHeader('Accept-Ranges', 'bytes');
  res.setHeader('Content_Range', `bytes ${start}-${end}/${totleSize}`);
  res.setHeader('Content_Length', end-start);
  return {
    code: 206,
    start: parseInt(start),
    end: parseInt(end)
  };
};

范围读取:

let rs;
const { code, start, end } = range(stats.size, req, res);
if (code === 200) {
  res.statusCode = 200;
  rs = fs.createReadStream(filePath);
} else {
  res.statusCode = 206;//表示是部分内容
  //创建一个流读取文件, {start, end}表示文件读取的起始点和终点
  rs = fs.createReadStream(filePath, { start, end });
}
 
//有这个pipe就不需要再去调用end了,这样直接调用end会导致res接受不到东西,因为pipe是异步的
rs.pipe(res);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
nodejs分页类代码分享
Jun 17 NodeJs
nodejs中的fiber(纤程)库详解
Mar 24 NodeJs
NodeJS中的MongoDB快速入门详细教程
Nov 11 NodeJs
nodejs读写json文件的简单方法(必看)
Mar 09 NodeJs
nodejs中使用HTTP分块响应和定时器示例代码
Mar 19 NodeJs
nodejs发送http请求时遇到404长时间未响应的解决方法
Dec 10 NodeJs
修改Nodejs内置的npm默认配置路径方法
May 13 NodeJs
nodejs实现套接字服务功能详解
Jun 21 NodeJs
详解NodeJS Https HSM双向认证实现
Mar 12 NodeJs
nodejs实现百度舆情接口应用示例
Feb 07 NodeJs
浅谈vue websocket nodeJS 进行实时通信踩到的坑
Sep 22 NodeJs
NodeJS配置CORS实现过程详解
Dec 02 NodeJs
NodeJS搭建HTTP服务器的实现步骤
Oct 12 #NodeJs
NodeJS服务器实现gzip压缩的示例代码
Oct 12 #NodeJs
nodejs aes 加解密实例
Oct 10 #NodeJs
nodejs读取本地中文json文件出现乱码解决方法
Oct 10 #NodeJs
nodejs require js文件入口,在package.json中指定默认入口main方法
Oct 10 #NodeJs
nodejs更新package.json中的dependencies依赖到最新版本的方法
Oct 10 #NodeJs
nodejs中用npm初始化来创建package.json的实例讲解
Oct 10 #NodeJs
You might like
Zend Framework教程之Zend_Helpers动作助手ViewRenderer用法详解
2016/07/20 PHP
js textarea自动增高并隐藏滚动条
2009/12/16 Javascript
javascript禁用Tab键脚本实例
2013/11/22 Javascript
jquery利用命名空间移除绑定事件的方法
2015/03/11 Javascript
JavaScript中的Math.atan2()方法使用详解
2015/06/15 Javascript
在JavaScript的正则表达式中使用exec()方法
2015/06/16 Javascript
深入理解JS实现快速排序和去重
2016/10/17 Javascript
Vue.js双向绑定操作技巧(初级入门)
2016/12/27 Javascript
微信小程序 解决swiper不显示图片的方法
2017/01/04 Javascript
vue mintui-Loadmore结合实现下拉刷新和上拉加载示例
2017/10/12 Javascript
Vue2.5通过json文件读取数据的方法
2018/02/27 Javascript
VUE实现可随意拖动的弹窗组件
2018/09/25 Javascript
Vuex中的State使用介绍
2019/01/19 Javascript
pageGroup.js实现分页功能
2019/07/27 Javascript
微信小程序实现页面跳转传递参数(实体,对象)
2019/08/12 Javascript
vue 添加和编辑用同一个表单,el-form表单提交后清空表单数据操作
2020/08/03 Javascript
antd配置config-overrides.js文件的操作
2020/10/31 Javascript
Python实现矩阵转置的方法分析
2017/11/24 Python
Python实现的tcp端口检测操作示例
2018/07/24 Python
Python 从列表中取值和取索引的方法
2018/12/25 Python
详解PyTorch中Tensor的高阶操作
2019/08/18 Python
python requests模拟登陆github的实现方法
2019/12/26 Python
pandas和spark dataframe互相转换实例详解
2020/02/18 Python
Anaconda3中的Jupyter notebook添加目录插件的实现
2020/05/18 Python
Win10环境中如何实现python2和python3并存
2020/07/20 Python
详解如何在PyCharm控制台中输出彩色文字和背景
2020/08/17 Python
Python爬虫分析微博热搜关键词的实现代码
2021/02/22 Python
Python字节单位转换(将字节转换为K M G T)
2021/03/02 Python
法国一家多品牌成衣精品中/高档商店:Graduate Store
2019/08/28 全球购物
俄罗斯卫浴采暖及维修用品超级市场:Dkrussia
2020/05/12 全球购物
上班离岗检讨书
2014/01/27 职场文书
学校端午节活动总结
2015/02/11 职场文书
开票证明
2015/06/23 职场文书
追悼会悼词大全
2015/06/23 职场文书
读《教育心理学》心得体会
2016/01/22 职场文书
css如何把元素固定在容器底部的四种方式
2022/06/16 HTML / CSS