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写的一个简单项目打包工具
May 11 NodeJs
Nodejs express框架一个工程中同时使用ejs模版和jade模版
Dec 28 NodeJs
angular2+nodejs实现图片上传功能
Mar 27 NodeJs
nodejs个人博客开发第五步 分配数据
Apr 12 NodeJs
详解nodejs微信jssdk后端接口
May 25 NodeJs
深入解析nodejs HTTP服务
Jul 25 NodeJs
Nodejs实现文件上传的示例代码
Sep 26 NodeJs
nodejs搭建本地服务器轻松解决跨域问题
Mar 21 NodeJs
基于nodejs res.end和res.send的区别
May 14 NodeJs
webpack打包nodejs项目的方法
Sep 26 NodeJs
基于Koa(nodejs框架)对json文件进行增删改查的示例代码
Feb 02 NodeJs
nodejs中使用archive压缩文件的实现代码
Nov 26 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
php 操作excel文件的方法小结
2009/12/31 PHP
php实现监控varnish缓存服务器的状态
2014/12/30 PHP
php用正则判断是否为数字的方法
2016/03/25 PHP
Yii2中多表关联查询hasOne hasMany的方法
2017/02/15 PHP
PHP实现的常规正则验证helper公共类完整实例
2017/04/27 PHP
php的无刷新操作实现方法分析
2020/02/28 PHP
javascript 获取元素位置的快速方法 getBoundingClientRect()
2009/11/26 Javascript
js计算精度问题小结
2013/04/22 Javascript
jQuery中is()方法用法实例
2015/01/06 Javascript
JavaScript实现文字与图片拖拽效果的方法
2015/02/16 Javascript
Shell脚本实现Linux系统和进程资源监控
2015/03/05 Javascript
实例讲解JavaScript的Backbone.js框架中的View视图
2016/05/05 Javascript
AngularJs表单验证实例详解
2016/05/30 Javascript
CSS3 media queries结合jQuery实现响应式导航
2016/09/30 Javascript
Javascript中的prototype与继承
2017/02/06 Javascript
Javascript 链式作用域详细介绍
2017/02/23 Javascript
Bootstrap布局之栅格系统学习笔记
2017/05/04 Javascript
vue中v-for加载本地静态图片方法
2018/03/03 Javascript
Vue使用lodop实现打印小结
2019/07/06 Javascript
基于Vue的侧边目录组件的实现
2020/02/05 Javascript
利用matplotlib+numpy绘制多种绘图的方法实例
2017/05/03 Python
对Python中DataFrame按照行遍历的方法
2018/04/08 Python
在Python中实现替换字符串中的子串的示例
2018/10/31 Python
解决Python 使用h5py加载文件,看不到keys()的问题
2019/02/08 Python
Django中多种重定向方法使用详解
2019/07/17 Python
django ManyToManyField多对多关系的实例详解
2019/08/09 Python
python使用pyecharts库画地图数据可视化的实现
2020/03/25 Python
python 利用panda 实现列联表(交叉表)
2021/02/06 Python
HTML5实现桌面通知 提示功能
2017/10/11 HTML / CSS
高性能钓鱼服装:Huk Gear
2019/02/20 全球购物
荣耀俄罗斯官网:HONOR俄罗斯
2020/10/31 全球购物
二年级小学生评语
2014/04/21 职场文书
领导班子对照检查材料
2014/09/22 职场文书
初中地理教学反思
2016/02/19 职场文书
个人售房合同协议书
2016/03/21 职场文书
使用 Apache Superset 可视化 ClickHouse 数据的两种方法
2021/07/07 Servers