zoukankan      html  css  js  c++  java
  • NodeJS4-6静态资源服务器实战_range范围请求

    range范围请求:向服务器发起请求可以申明我想请求判断内容的范围,从多少个字节到多少个字节,一次要求把所有的内容拿回来,服务器在得到相应的请求之后,从拿到对应的文件,拿到对应的字节返回给客户端.要实现这一功能,请求的时候在RequestHeaders里面放一个range对象和我们定义的范围,都好分割请求多个范围,

    • range:bytes = [ start ] - [ end ]

      在RequestHeaders里面放一个range对象和我们定义的范围,逗号分割请求多个范围,

    • Accept-Ranges:bytes  

      在响应中加一个响应头,这里表示服务器可以处理的格式字节

    • Content-Range:bytes start-end/total

      需要在ResponseHeaders中返回Content-Range表示返回给你的十字街,从哪里开始那里结束

    添加一个文件处理range请求,添加range.js

    /*参数
        totalSize 需要整个的字节数 , 
        req 读到客户端请求range的方位
        resp
    */
    module.exports = (totalSize,req,res) =>{
        const range = req.headers['range'];
        //如果拿不到range就返回200,告诉它处理不了
        if(!range){
            return { code:200 };
        }
    
        const sizes = range.match(/bytes=(d*)-(d*)/)
        const end = sizes[2] || totalSize - 1;
        const start = sizes[1] || totalSize - end;
        //异常情况,返回200
        if(start > end || start < 0 || end > totalSize){
            return {code:200};
        }
    
        //设置头部
        res.setHeader('Accept-Range','bytes');
        res.setHeader('Content-Range',`bytes ${start} - ${end} / ${total} `)
        res.setHeader('Content-Length',end - start)
        //可以处理的情况返回以下结果
        return {
            code : 206,
            start:parseInt(start),
            end:parseInt(end)
        }
    }

    在route.js引入range.js

    const fs =require('fs')
    const path = require('path')
    const Handlebars = require('handlebars')
    const promisify = require('util').promisify;
    const stat = promisify(fs.stat)
    const readdir = promisify(fs.readdir);
    // //引用range范围
    // const range = require('./range')
    const config = require('../config/defaultConfig')
    const tplPath = path.join(__dirname,'../template/dir.tpl')
    const source = fs.readFileSync(tplPath);
    const template = Handlebars.compile(source.toString())
    //引入新加的mime,对contentType的判断
    const mime = require('./mime')
    const compress = require('./compress')
    
    //引用range范围
    const range = require('./range')
    
    module.exports=async function(req,res,filePath){
        try{
            const stats =await stat(filePath)
            if(stats.isFile()){
                const contentType = mime(filePath)
                res.statusCode = 200
                res.setHeader('content-Type',contentType)
                
                let rs;
                const {code,start,end} = range(stats.size, req, res)
                if(code === 200){
                    res.statusCode = 200
                    rs = fs.createReadStream(filePath) 
                }else{
                    res.statusCode = 216 //测试随便定
                    rs = fs.createReadStream(filePath,{start,end}) 
                }
    
                // let rs = fs.createReadStream(filePath) 
                if(filePath.match(config.compress)){
                    rs = compress(rs,req,res)
                }
                rs.pipe(res);
                // fs.readFile(filePath,(err,data)=>{
                //     res.end(data)
                // });
            }else if(stats.isDirectory()){
                //所有异步调用必须用await
                const files =await readdir(filePath);
                res.statusCode = 200
                res.setHeader('content-Type','text/html')
                const dir = path.relative(config.root,filePath)
                const data = {
                    title:path.basename(filePath),
                    // dir:config.root,
                    dir:dir?`/${dir}`:'',
                    files:files.map(file=>{
                        return {
                            file,
                            icon:mime(file)
                        }
                    })
                }
                res.end(template(data));
            }
        }catch(ex){
            console.error(ex);
            res.statusCode = 404
            res.setHeader('content-Type','text/plain')
            res.end(`${filePath} is not a directory or file
     ${ex.error}`)
        }
    }

    主要改变是红框这部分

    安装curl来查看,运行

    curl -r 0-2 -i http://127.0.0.1:9527/LICENSE

    运行结果

  • 相关阅读:
    1、Jenkins的安装与简单配置
    2、jenkins+svn自动发布和回滚
    关于kafka生产者相关监控指标的理解(未解决)
    Zabbix中获取各用户告警媒介分钟级统计
    2-4、配置Filebeat使用logstash
    JS基础 浏览器弹出的三种提示框(提示信息框、确认框、输入文本框)
    C# winform 托盘控件的使用
    c# 将两个表的有效数据合到一个表中
    C# 认识 接口
    let 和 var 定义变量的区别
  • 原文地址:https://www.cnblogs.com/chorkiu/p/11430651.html
Copyright © 2011-2022 走看看