HTTP/2 兼容 API,如何处理
Posted
技术标签:
【中文标题】HTTP/2 兼容 API,如何处理【英文标题】:HTTP/2 compatibility API, how to handle it 【发布时间】:2022-01-16 14:21:09 【问题描述】:虽然我最初决定创建一个仅 HTTP/2 的服务器,但我发现兼容性 API 是一个不错的选择,可以支持不支持或不支持 HTTP/2 的客户端(fetch
in react-native
?) .
但是,我很难理解如何处理 HTTP/1x 处理程序上的传入请求,报告 req.httpVersion === "2.0"
。以下代码摘自nodejs
文档中的ALPN negotiation section
:
function onRequest(req, res)
// Detects if it is a HTTPS request or HTTP/2
const socket: alpnProtocol = req.httpVersion === '2.0' ?
req.stream.session : req;
// HERE: OK, say we have req.httpVersion === '2.0'
// Now, what?
res.writeHead(200, 'content-type': 'application/json' );
res.end(JSON.stringify(
alpnProtocol,
httpVersion: req.httpVersion
));
首先,我不明白上面的代码应该做什么。就像,我知道它的作用,但它没有什么特别之处——似乎只是通用的 HTTP/1x 请求处理程序,它会发送一些 JSON,仅此而已。我错过了什么吗?
除此之外:
一旦 HTTP/1x 处理程序报告req.httpVersion = "2.0"
,我该怎么办?
它是否也会由 HTTP/2 处理程序 (server.on("stream", ()=> ... )
) 处理,所以我应该在 HTTP/1x 处理程序中忽略它?
如果 HTTP/2 处理程序不能自动处理它,我可以而且应该手动将请求转发给 HTTP/2 处理程序吗?
function http2handler(stream, headers) ...
function http1xhandler(req, res)
if (req.httpVersion === "2.0")
// handle as HTTP/2
return http2handler(req.stream, req.headers);
// handle as HTTP/1x ...
const server = createSecureServer(
cert, key, allowHTTP1: true ,
http1xhandler
).listen(4443);
server.on("stream", http2handler);
如果以上都不是,示例中的响应 JSON 是否在向客户端指示它应该切换到 HTTP/2 方面发挥作用?如果是这样,客户具体应该怎么做?
对不起,如果这可能是一个愚蠢的问题,nodejs 文档很糟糕......似乎他们的每一点文档都必须以悬念结束......
【问题讨论】:
【参考方案1】:在摆弄了一些代码并阅读了更多的文章和答案之后,我想我终于明白了发生了什么。但是,如果我在这里说的任何内容有误,我将不胜感激。
HTTP/2 兼容性 API 为 HTTP/1x 和 HTTP/2 请求提供通用请求处理程序。如ALPN negotiation documentation 所示,开发人员应限制对公共 HTTP/1x API 的响应 - 直到识别出 HTTP/2 请求。您可以检查req.httpVersion
来识别这些,并根据需要分支您的代码。
如果您同时指定兼容性请求处理程序(createSecureServer
上的回调函数)和on("stream", ...)
事件处理程序(仅限 HTTP/2),则服务器行为是:
on("stream", ...)
请求处理程序将被调用 - 但只有一个处理程序应该响应请求。如果您尝试响应来自两个处理程序的请求,您将获得:Error [ERR_HTTP2_HEADERS_SENT]: Response has already been initiated.
我选择处理这些问题的方法是创建独立的HTTP/1x
和HTTP/2
处理程序,每个处理程序都处理自己的蛋糕。兼容性处理程序应忽略 HTTP/2 请求。在代码中:
function http1xhandler(req, res)
if (req.httpVersion === "2.0")
// Ignore HTTP/2 requests, will be handled by the on("stream", ...) event handler
// Or, you can answer the HTTP/2 request here, using HTTP/2 features as well
return;
// Handle HTTP/1x request
res.writeHead(200, 'content-type': 'text/plain' );
res.end("Hello HTTP/1x!");
const server = createSecureServer(
cert, key, allowHTTP1: true ,
http1xhandler
).listen(4443);
// Do not use the following if you are handling
// HTTP/2 in the HTTP/1x compatibility callback
function http2handler(stream, headers)
stream.respond(
'content-type': 'text/plain; charset=utf-8',
':status': 200
);
stream.end("Hello HTTP/2!");
server.on("stream", http2handler);
希望这对研究这些 API 的其他人有用。
【讨论】:
以上是关于HTTP/2 兼容 API,如何处理的主要内容,如果未能解决你的问题,请参考以下文章
WooCommerce REST API v2:如何处理付款?