nodejs http2 文件推送

请自行准备https证书, 本项目使用了mime 包判断文件类型。
index.html 和 cook.js 和 server.js 放在同一目录下面。
http2 的推送效果如下。

没有推送

QQ图片20181102171850.png

可以看见一共请求了2次,第一次加载html,第二次加载cook.js。耗时84ms。

开启推送

QQ截图20181102172235.png

开启推送后 加载cook.js 变成了 Push, 并且 加载cook.js耗时变成了 2ms。共耗时47ms。

注意事项

启动项目后使用https 访问你的服务地址而不是 http。 一般浏览器输入地址默认为http。
例如我的代码访问地址 https://127.0.0.1。
想实验推送效果记得清除浏览器缓存。

下面是代码。

index.html




    
    Title


456

cook.js

console.log(123)

server.js

const http2 = require('http2');
const fs = require('fs');
const mime = require('mime');
const options = {
    key: fs.readFileSync('bq.key'),
    cert: fs.readFileSync('bq.crt')
};

const server = http2.createSecureServer(options);
server.on('error', (err) => console.error(err));

function getHead(fd, path,callBack) {
    fs.fstat(fd, function (err,stat) {
        if (err) {
            stream.end('notFound');
            return;
        }
        const head = {
            'content-length': stat.size,
            'last-modified': stat.mtime.toUTCString(),
            'content-type': mime.getType(path)
        };
        callBack(head);
    });
}


function sendFile (stream, path) {
    fs.open(path, 'r', (err, fd) => {
        if (err) {
            stream.end('notFound');
            return;
        }
        try{
            getHead(fd, path,function (head) {
                stream.respondWithFD(fd, head, { waitForTrailers: false });
                stream.on('close', () => fs.closeSync(fd));
            });
        }catch (e) {
            console.log(e);
        }
    });
}

server.on('stream', (stream, headers) => {
    let path = headers[':path'];
    if (path === '/') {
        path = '/index.html';
    }
    path = '.' + path;
    sendFile(stream, path);
    // 当请求的是index.html, 把cook.js 推过去。
    if (path === './index.html') {
        // stream.pushStream({ ':path': '/cook.js' }) 这里的的path 是浏览器将会请求的文件地址。
        // 把它推给浏览器后,浏览器解析html 后请求cook.js 会发现自己已经有了就不在请求了。
        stream.pushStream({ ':path': '/cook.js' }, (err, pushStream, headers) => {
            if (err) throw err;
            sendFile(pushStream, './cook.js');
        });
    }
});

server.listen(443);

你可能感兴趣的:(nodejs http2 文件推送)