Node.js中HTTP请求对象的headers属性未出现在Object.keys()结果中的原因及相关文档咨询
Node.js中HTTP请求对象的headers属性未出现在Object.keys()结果中的原因及相关文档咨询
嘿,这个问题我之前也碰到过,其实核心原因和Node.js里对象属性的可枚举性以及**访问器属性(getter)**有关,我给你拆解下:
为什么headers不在Object.keys(req)里?
Node.js的http.IncomingMessage(也就是你拿到的req对象)的headers属性是一个访问器属性(getter),它并不是对象自身的可枚举属性。而Object.keys()方法只会返回对象自身的、可枚举的属性,所以自然不会把headers列出来。
相反,rawHeaders是req对象自身的可枚举属性,所以会出现在Object.keys(req)的结果里。
两者的区别是什么?
rawHeaders:是一个原始的字符串数组,严格按照HTTP请求头的顺序,以[key, value, key, value]的格式存储,没有做任何格式化处理。你贴的调试信息里也能看到它的结构:
["host","localhost:5001","connection","keep-alive","pragma","no-cache","cache-control","no-cache","sec-ch-ua","\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Google Chrome\";v=\"120\"","sec-ch-ua-mobile","?0","sec-ch-ua-platform","\"Linux\"","dnt","1","upgrade-insecure-requests","1","user-agent","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","sec-fetch-site","same-origin","sec-fetch-mode","navigate","sec-fetch-user","?1","sec-fetch-dest","document","accept-encoding","gzip, deflate, br","accept-language","en-US,en;q=0.9,it-IT;q=0.8,it;q=0.7","cookie","amp-access=amp-7JjY8O_xkojgphlXHw-5rg; _ga=GA1.1.1937988494.1707261141; _ga_EPYLVLZHVN=GS1.1.1707261141.1.1.1707261271.0.0.0"]
headers:是通过getter动态生成的对象,Node.js内部会把rawHeaders里的键值对整理成更易用的键值对形式,还会自动将所有头名称转换为小写(比如把Host变成host),方便你直接通过req.headers.host这种方式访问。你贴的调试信息里它的结构是:
{"host":"localhost:5001","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","sec-ch-ua":"\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\", \"Google Chrome\";v=\"120\"","sec-ch-ua-mobile":"?0","sec-ch-ua-platform":"\"Linux\"","dnt":"1","upgrade-insecure-requests":"1","user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","sec-fetch-site":"same-origin","sec-fetch-mode":"navigate","sec-fetch-user":"?1","sec-fetch-dest":"document","accept-encoding":"gzip, deflate, br","accept-language":"en-US,en;q=0.9,it-IT;q=0.8,it;q=0.7","cookie":"amp-access=amp-7JjY8O_xkojgphlXHw-5rg; _ga=GA1.1.1937988494.1707261141; _ga_EPYLVLZHVN=GS1.1.1707261141.1.1.1707261271.0.0.0"}
怎么验证这个结论?
你可以用Object.getOwnPropertyDescriptor()方法查看headers的属性描述符:
console.log(Object.getOwnPropertyDescriptor(req, 'headers'));
输出结果里会看到enumerable: false,这就说明它是不可枚举的,所以不会被Object.keys()捕获。
如果想查看req对象的所有自身属性(包括不可枚举的),可以用Object.getOwnPropertyNames(req),这个方法会返回包含headers在内的所有自身属性名。
相关文档参考
在Node.js官方文档的http.IncomingMessage类章节里,对headers和rawHeaders都有明确说明:
headers:明确指出它是一个由原始请求头解析而来的对象,头名称均为小写。rawHeaders:说明它是未处理的原始请求头数组,按收到的顺序排列。
另外,关于对象属性的可枚举性和访问器属性的基础知识,可以参考Node.js文档里关于对象属性描述符的部分,不过针对这个问题,直接看http模块的IncomingMessage文档就足够啦。
备注:内容来源于stack exchange,提问作者Ralph Yozzo
相关产品推荐
相关产品推荐

