使用Node.js pushStream方法的服务器推送不起作用 [英] Server Push with Nodejs pushStream method is not working

查看:198
本文介绍了使用Node.js pushStream方法的服务器推送不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究nodejs上的http2,但是发现问题pushStream方法不起作用

I am studying http2 on nodejs, but find out a issue pushStream method not working

(客户端在开发人员工具上不显示"Pushed/[fileName]")

我想知道原因是否为nodejs版本(我安装了最新版本v9.8.0)

I wonder if the reason is nodejs version (I installed the latest version v9.8.0)

我的代码如下:

server.js

'use strict'

const fs = require('fs');
const path = require('path');
const http2 = require('http2');
const utils = require('./utils');

const { HTTP2_HEADER_PATH } = http2.constants;

const PORT = process.env.PORT || 3000;

// The files are pushed to stream here
function push(stream, path) {
  const file = utils.getFile(path);
  if (!file) {
    return;
  }
  stream.pushStream({ [HTTP2_HEADER_PATH]: path}, (err, pushStream, headers) => {
    if (err) throw err;
    pushStream.respondWithFD(file.content, file.headers)
  });
}

// Request handler
function onRequest(req, res) {
  const reqPath = req.headers[':path'] === '/' ? '/index.html' : req.headers[':path']
  const file = utils.getFile(reqPath);

  // 404 - File not found
  if (!file) {
    res.statusCode = 404;
    res.end();
    return;
  }

  // Push with index.html
  if (reqPath === '/index.html') {
    push(res.stream, '/assets/main.js');
    push(res.stream, '/assets/style.css');
  } else {
    console.log("requiring non index.html")
  }

  // Serve file
  res.stream.respondWithFD(file.content, file.headers);
}

// creating an http2 server
const server = http2.createSecureServer({
  cert: fs.readFileSync(path.join(__dirname, '/certificate.crt')),
  key: fs.readFileSync(path.join(__dirname, '/privateKey.key'))
}, onRequest);

// start listening
server.listen(PORT, (err) => {
  if (err) {
    console.error(err);
    return -1;
  }
  console.log(`Server listening to port ${PORT}`);
});

utils.js

'use strict';
const fs = require('fs');
const mime = require('mime');

module.exports = {
  getFile: function (path) {
    const filePath = `${__dirname}/public${path}`;
    try {
      const content = fs.openSync(filePath, 'r');
      const contentType = mime.getType(filePath);
      return {
        content,
        headers: {
          'content-type': contentType
        }
      };
    } catch (e) {
      return null;
    }
  }
}

更新2020 01 28

已解决:原因是chrome v65的最新版本.有错误,导致客户端不信任PUSH_PROMISE框架.我备份了Chrome v64,然后就可以正常工作了.

Resolved: The reason is the latest version of chrome v65. has bug, cause client do not trust PUSH_PROMISE frame. I backup chrome v64 then it working now.

推荐答案

我没有尝试运行您的代码,但是注意到Chrome不允许使用不受信任的HTTPS证书(例如,自签名证书)进行HTTP/2推送尚未添加到信任库). 向Chrome浏览器团队提出了一个错误.

I haven’t tried to run your code but have noticed that Chrome does not allow HTTP/2 push with an untrusted HTTPS certificate (e.g. a self-signed one not yet added to the trust store). Raised a bug with the Chrome team.

如果您有红色的不安全挂锁物品,那么您也可能遇到此问题.将证书添加到您的信任存储中,重新启动Chrome并重新加载您应该获得绿色挂锁的网站.

If you have the red unsecure padlock item then you could be hitting this issue too. Add the certificate into your trust store, restart Chrome and reload the site where you should get a green padlock.

请注意,Chrome需要具有与域匹配的主题备用名称(SAN)字段的证书,因此,如果您只有较旧的主题字段,那么即使将其添加到您的信任库中也不会变成绿色.

Note Chrome needs a certificate with a Subject Alternative Name (SAN) field matching the domain so if you’ve just got the older Subject field then it won’t go green even after adding it to your trust store.

另一种选择是通过在URL中键入以下内容来查看Chrome HTTP2框架:

Another option is to look at the Chrome HTTP2 frames by typing this into your URL:

chrome://net- internals/#http2

如果看到推送承诺帧(带有promised_stream_id),然后是该promised_stream_id上的标头和数据,则表明服务器端正在工作.

If you see the push promise frames (with a promised_stream_id), followed by the headers and data on that promised_stream_id then you know the sever side is working.

这篇关于使用Node.js pushStream方法的服务器推送不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆