流(读一点、发一点):
1.读取流:fs.createReadStream、req
2.写入流:fs.createWriteStream、res
3.读写流:压缩、加密
使用流+压缩进行操作:
const zlib = require('zlib')
const fs = require('fs')
let rs = fs.createReadStream('www/jquery.js')//读取流
let ws = fs.createWriteStream('www/jquery.js.gz')//输出流
let gz = zlib.createGzip()
rs.pipe(gz).pipe(ws)//通过pipe连接读取流、压缩操作、输出流
rs.on('error',err=>{//监听是否有读取失败
console.log('读取失败',err);
})
ws.on('finish',()=>{//监听输出流的finish事件
console.log('完成')
})
结果
对于服务器来说,一般不会输出源文件给客户端(html、js、css等各种从服务器请求的资源),一般都是压缩后的文件,这样可以节省带宽流量
下面做一个服务器返回资源的演示
- 先看不压缩的演示
const zlib = require('zlib')
const fs = require('fs')
const http = require('http')
let server = http.createServer((req,res)=>{
let rs = fs.createReadStream(`www${req.url}`)//读取流
rs.pipe(res)//不压缩,直接读取请求的url,然后输出给res
//let gz = zlib.createGzip()//压缩后输出
//rs.pipe(gz).pipe(res)
rs.on('error',err=>{
res.writeHeader(404)
res.write('Not Found')
res.end()
})
})
server.listen(5000)
可以看到jquery.js大小288KB
然后注释掉上面代码不压缩的方式,改为压缩方式
//rs.pipe(res)//不压缩,直接读取请求的url,然后输出给res
let gz = zlib.createGzip()//压缩后输出
rs.pipe(gz).pipe(res)
发现文件被下载了......
这是因为response header里没有设置content-encoding: gzip,导致浏览器将返回的文件以普通文件(二进制格式)来解析。事实上,观察大部分网页的response header里都设置了content-encoding: gzip:
所以需要在代码里加一句:
res.setHeader('content-encoding','gzip')
这里注意一下res.setHeader和res.writeHeader的区别,前者是设置header里的属性,后者是覆盖整个header
观察到文件已成功压缩: