Node 搭建一个静态资源服务器的实现

2020-06-17 05:51:05易采站长站整理

response.setHeader("Content-Encoding", 'gzip')
return readStream.pipe(zlib.createGzip())
}
else if (acceptEncoding.match(/bdeflateb/)) {
response.setHeader("Content-Encoding", 'deflate')
return readStream.pipe(zlib.createDeflate())
}
}

修改 route.js 文件读取的代码:


// server/route.js
const compress = require('./compress')
···
if (stats.isFile()) {
const mimeType = mime(filePath)
response.statusCode = 200
response.setHeader('Content-Type', mimeType)

// fs.createReadStream(filePath).pipe(response)
+ let readStream = fs.createReadStream(filePath)
+ if(filePath.match(config.compress)) { // 正则匹配:/.(html|js|css|md)/
readStream = compress(readStream,request, response)
}
readStream.pipe(response)
}

运行 server 可以看到不仅 response header 增加压缩标志,而且 3K 大小的资源压缩到了 1K,效果明显:

七、资源缓存

以上的 Node 服务都是浏览器首次请求或无缓存状态下的,那如果浏览器/客户端请求过资源,一个重要的前端优化点就是缓存资源在客户端。 缓存有强缓存和协商缓存

强缓存在 Request Header 中的字段是 Expires 和 Cache-Control;如果在有效期内则直接加载缓存资源,状态码直接是显示 200。

协商缓存在 Request Header 中的字段是:

If-Modified-Since(对应值为上次 Respond Header 中的 Last-Modified)
If-None—Match(对应值为上次 Respond Header 中的 Etag)

如果协商成功则返回 304 状态码,更新过期时间并加载浏览器本地资源,否则返回服务器端资源文件。

首先配置默认的 cache 字段:


// server/config.js
module.exports = {
root: process.cwd(),
host: '127.0.0.1',
port: '8877',
compress: /.(html|js|css|md)/,
cache: {
maxAge: 2,
expires: true,
cacheControl: true,
lastModified: true,
etag: true
}
}

新建 server/cache.js,设置响应头:


const config = require('./config')
function refreshRes (stats, response) {
const {maxAge, expires, cacheControl, lastModified, etag} = config.cache;

if (expires) {
response.setHeader('Expires', (new Date(Date.now() + maxAge * 1000)).toUTCString());
}
if (cacheControl) {
response.setHeader('Cache-Control', `public, max-age=${maxAge}`);
}
if (lastModified) {
response.setHeader('Last-Modified', stats.mtime.toUTCString());
}
if (etag) {
response.setHeader('ETag', `${stats.size}-${stats.mtime.toUTCString()}`); // mtime 需要转成字符串,否则在 windows 环境下会报错