问题描述
我正在尝试从异步钩子 IncomingMessage
提供的 HTTPINCOMINGMESSAGE
实例中获取 HTTP 标头和 HTTP 正文:
import asyncHooks = require("async_hooks");
import { IncomingMessage } from "http";
asyncHooks.createHook({
init: (
asyncId: number,type: string,triggerAsyncId: number,req: IncomingMessage
) => {
if (type !== "HTTPINCOMINGMESSAGE") return;
// Where are the HTTP headers?
console.log(req.headers); // prints `undefined`
// How do I get the HTTP body?
console.log(req.on); // prints `undefined`
// Yet,`req` is an `IncomingMessage`,the same than following `req`:
//
// const http = require('http');
// http.createServer((req,res) => {
// // The HTTP request headers are available here!
// console.log(req.headers);
// // `req` is an `IncomingMessage` as well
// console.log(req.constructor===IncomingMessage); // prints `true`
// });
//
console.log(req.constructor===IncomingMessage); // prints `true`
},})
.enable();
我已经深入研究了 Node.js 源代码,但没有运气。我找不到填充 req.headers
的代码,也找不到创建 HTTP 正文流的代码。
编辑
总体目标是使 Wildcard API 能够提供context
:
import { context } from '@wildcard-api/server';
// Wildcard saves a cookie on behaf of the Wildcard user,and exposes
// the value saved in the cookie over an ES6 proxy `context`.
function called_somewhere_within_an_HTTP_Request_lifecycle() {
// Wildcard uses Async Hooks to be able to kNow the HTTP request associated
// with the following `context.userName` ES6 proxy getter call,and therefore
// can provide the value `userName` saved in the cookie of the HTTP request.
console.log(context.userName);
}
解决方法
不应使用异步钩子来修改程序行为。创建此 API 是为了跟踪异步资源,例如来衡量绩效。尝试以这种方式修改程序会导致未定义的行为和不可预测的错误。
您可以对 NodeJS 的 HTTP 库进行猴子补丁,但我强烈建议您避免使用它。