美文网首页
Node.js 静态服务器新知

Node.js 静态服务器新知

作者: 圆儿圈圈 | 来源:发表于2018-03-02 18:02 被阅读0次

用node http模块搭建服务器一直被用作项目实践及开发,深入学习后,对node搭建http服务器有了新的了解和认识,写此文总结罗列一下

  • 支持gzip压缩
  • 缓存支持/控制
  • yargs与自动化

Gzip

GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNIX系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式,或者说一种文件格式。HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中的网站时,服务器中的这个功能就将网页内容压缩后传输到来访的电脑浏览器中显示出来.一般对纯文本内容可压缩到原大小的40%.这样传输就快了,效果就是你点击网址后会很快的显示出来.当然这也会增加服务器的负载. 一般服务器中都安装有这个功能模块的.

image image

HTTP 请求头 Accept-Encoding 会将客户端能够理解的内容编码方式——通常是某种压缩算法——进行通知。通过内容协商的方式,服务端会选择一个客户端提议的方式,使用并在响应报文首部 Content-Encoding 中通知客户端该选择。

Accept-Encoding:gzip, deflate, br//当前请求支持格式为gzip,defalte,br

Content-Encoding:gzip // 当前内容压缩格式为gzip

可以用命令行设置请求 Accept-Encoding头

curl -v -H "Accept-Encoding:deflate" http://localhost:8080/msg.txt

http与Gzip

function request(req, res) {
    let { pathname } = url.parse(req.url);// /msg.txt
    //D:\vipcode\201801\16.http\msg.txt
    let filepath = path.join(__dirname, pathname);
    try {
        // await is only valid in async function
        let statObj = await stat(filepath);
        //可以根据不同的文件内容类型返回不同的Content-Type
        res.setHeader('Content-Type', mime.getType(pathname));
        //为了兼容不同的浏览器,node把所有的请求头全转成了小写
        let acceptEncoding = req.headers['accept-encoding'];
        // 内容协商
        if (acceptEncoding) {
            if (acceptEncoding.match(/\bgzip\b/)) {
                //服务器告诉 客户端我用什么压缩方法压缩了
                res.setHeader('Content-Encoding', 'gzip');
                fs.createReadStream(filepath).pipe(zlib.createGzip()).pipe(res);
            } else if (acceptEncoding.match(/\bdeflate\b/)) {
                res.setHeader('Content-Encoding', 'deflate');
                fs.createReadStream(filepath).pipe(zlib.createDeflate()).pipe(res);
            } else {
                fs.createReadStream(filepath).pipe(res);
            }
        } else {
            fs.createReadStream(filepath).pipe(res);
        }
    } catch (e) {
        res.statusCode = 404;
        res.end();
    }
}

根据拿到的 req.headers['accept-encoding'];类型对请求的静态资源进行相同类型的压缩

fs.createReadStream(filepath).pipe(zlib.xxx()).pipe(res);
tip:可以用util模块中的promisify 将一个异步方法转出一个返回promise的方法 (node v8以上)
let { promisify } = require('util'); 
let stat = promisify(fs.stat);

cache

缓存可以减少对服务器的请求,加快请求效率

  • lastModify
  • etag
  • expires
lastModify 通过最后修改时间来判断缓存是否可用
fs.stat(filepath, (err, stat) => {
        if (err) {
            return sendError(req, res);
        } else {
            let ifModifiedSince = req.headers['if-modified-since'];//请求头资源上次修改时间
            let LastModified = stat.ctime.toGMTString();//文件上次修改时间
            if (ifModifiedSince == LastModified) {// 如果相等则返回304
                res.writeHead(304);
                res.end('');
            } else {
                return send(req, res, filepath, stat);
            }
        }
    });
ETag是实体标签的缩写,根据实体内容生成的一段hash字符串,可以标识资源的状态。当资源发生改变时,ETag也随之发生变化。 ETag是Web服务端产生的,然后发给浏览器客户端。
fs.stat(file, (err, stat) => {
        if (err) {
            sendError(err, req, res, file, stat);
        } else {
            let ifNoneMatch = req.headers['if-none-match'];
            let etag = crypto.createHash('sha1').update(stat.ctime.toGMTString() + stat.size).digest('hex');
            if (ifNoneMatch) {
                if (ifNoneMatch == etag) {
                    res.writeHead(304);
                    res.end();
                } else {
                    send(req, res, file, etag);
                }
            } else {
                send(req, res, file, etag);
            }
        }
    });
设置服务器响应消息头字段Expires
res.setHeader('Expires', expires.toUTCString());
res.setHeader('Cache-Control', 'max-age=60');

自动化

mac新建自动化shell脚本区别与windows

$ touch hello.sh

$ chmod +x hello.sh

$ ./hello.sh

安装yargs

yargs 模块能够解决如何处理命令行参数。它也需要安装。
npm i yargs --save

编辑hello.sh

let yargs = require('yargs');
//它可以帮我们解析命令行参数,把参数数组变成对象的形式
// -n  --name
let argv = yargs.options('n', {
    alias: 'name',//别名
    demand: true,//必填
    default: 'yuanyuan',
    description: '请输入你的姓名'
})
    .usage('hellp [opitons]')
    .help()//指定帮助信息
    .example('hello -name yuanyuan', '执行hello命令,然后传入name参数为yuanyuan')
    .alias('h', 'help')
    .argv;
console.log(argv);

console.log('hello ' + argv.name);

添加package.json,并添加以下内容

{
  "name": "hello",
  "bin": {
    "hello": "hello"
  }
}

执行 npm link 命令。

$ npm link

就可以直接执行 hello命令了

相关文章

  • Node.js 静态服务器新知

    用node http模块搭建服务器一直被用作项目实践及开发,深入学习后,对node搭建http服务器有了新的了解和...

  • 当前文集 node.js 写一个静态资源服务器记录,是为了给自己学习用 node.js 写静态资源服务器做一个记录...

  • node.js静态页面服务器

    node.js静态页面服务器 const http = require('http'); const url re...

  • java Socket 实现多线程静态文件服务器

    关于静态文件服务器,我觉得博文共赏:Node.js静态文件服务器实战写的不错,简单易懂,思路清晰,不过使用Node...

  • 工程优化方案:动静分离

    《深入浅出 Node.js》阅读随笔 将静态资源,比如图片、音频、视频、样式文件等,存放在专门的静态资源服务器上,...

  • Node.js搭建静态服务器

    写在开头,本文是node.js最最初级的搭建静态服务器,比较适合新手入门,大神请绕道哦~ Node.js 是一个基...

  • XDL_NO.5 Node.js 中的I/O交互

    回顾下上节课的知识点 搭建一个简单的 Node.js 服务器 利用Node.js 搭建一个静态网站 今天的主题是:...

  • Node.js搭建本地静态服务器

    Node.js搭建本地静态服务器 了解网络 HTTP(超文本传输协议) 主要内容 请求 响应 连接(三次握手) 断...

  • 初学NODE 学习笔记(二)-常用内置模块

    (二)用node.js内置模块,模拟搭建简单服务器(静态资源文件请求的处理); 明确:NODE是用来开发后台,服务...

  • 搭建Web服务器-Node.js

    Node.js介绍 Node.js 是一种新兴的服务器语言,用 Javascript开发服务器。 Node.js ...

网友评论

      本文标题:Node.js 静态服务器新知

      本文链接:https://www.haomeiwen.com/subject/gctzxftx.html