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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>456</h1>
<script src="./cook.js"></script>
</body>
</html>

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 會發(fā)現自己已經有了就不在請求了。
        stream.pushStream({ ':path': '/cook.js' }, (err, pushStream, headers) => {
            if (err) throw err;
            sendFile(pushStream, './cook.js');
        });
    }
});

server.listen(443);

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,008評論 25 709
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 13,983評論 2 59
  • 兩個自相矛盾的觀點肯定有一個是對的,我們可以自相矛盾,到這個自相矛盾要用兩個不同的事實來說明,在避免自相矛盾...
    姜楊Ada閱讀 186評論 0 0
  • 一、 MyBatis的初始化做了什么 任何框架的初始化,無非是加載自己運行時所需要的配置信息。 MyBatis的配...
    消失er閱讀 1,415評論 0 3
  • 學了不短時間的java,有點零散,準備串聯起知識,決定寫一個綜合的程序來鍛煉鍛煉,于是花了幾天做了一個簡單的NoS...
    Rancho123閱讀 535評論 1 2

友情鏈接更多精彩內容