Sails 中 req.get() 方法:大小写不敏感的请求头读取与底层实现全解析
后端【免费下载链接】sailsRealtime MVC Framework for Node.js项目地址https://gitcode.com/gh_mirrors/sa/sails点击查看免费下载导读在 Sails基于 Node.js 的实时 MVC 框架中req.get()是控制器、策略policy与自定义中间件里读取 HTTP 请求头header的标准入口。本文以官方 API 参考文档 docs/reference/req/req.get.md 为核心系统讲解req.get()的签名、行为约定大小写不敏感、referrer/referer同义与完整示例并结合本仓库核心源码lib/router/req.js、lib/hooks/request/metadata.js 等剖析其底层实现与 Sails 内部的真实调用场景帮助你正确、高效地在自己的应用中使用请求头信息。一、req.get()是什么req.get(header)用于返回当前请求req中指定 header 字段的值。它是 Sails 与 Express/Connect 中间件生态保持兼容的核心方法之一——无论是来自真实 HTTP 服务器的请求还是通过虚拟路由器virtual router例如 Sails Socket 的虚拟请求构造的请求都能通过同一套 API 读取请求头。签名req.get(header);headerString请求头字段名例如Host、Accept、X-Forwarded-Host、Content-Type。返回值该请求头的值String如果请求中不存在该字段返回undefined。基本示例假设req中包含名为myField、值为cat的请求头req.get(myField); // - cat二、两个关键行为约定官方文档在 Notes 中明确了两条规则这两条规则在源码中均有直接对应实现。1. header 参数大小写不敏感HTTP 协议本身规定 header 名不区分大小写req.get()严格遵循这一约定。无论你传入host、Host还是HOST都能取到同一个值req.get(host); req.get(Host); req.get(HOST); // 三者返回相同结果从源码看这一行为来自两层保障存储层lib/router/mock-req.js 在构造模拟请求对象时将传入的 headers 的所有键统一转换为小写后存储self.headers[key.toLowerCase()] val;从根上保证了查找的一致性。读取层lib/router/req.js 中req.get()的实现首先将传入的参数名toLowerCase()再与已小写化的 headers 做匹配。2.referrer与referer互为同义词HTTP 规范中本应使用Referer正确拼写为 referrer但标准里写错了因此实际请求中两种拼写都可能出现。req.get()将两者视为同义词无论传哪个名字、请求里出现的是哪个拼写都能正确取到来源页地址req.get(referrer); req.get(referer); // 请求头为 Referer 或 Referrer 时两者返回相同结果这直接对应 lib/router/req.js 中的 switch 分支req.get req.header function (name) { switch (name name.toLowerCase()) { case referer: case referrer: return this.headers.referrer || this.headers.referer; default: return this.headers[name]; } };实现采用“先查referrer再回退referer”的顺序保证无论客户端发送哪种拼写都能命中。三、源码级实现虚拟请求 vs 真实 HTTP 请求Sails 的req对象具有“传输无关”transport-agnostic特性。要深入理解req.get()需要区分两种请求来源。1. 虚拟请求virtual request当请求不是来自真实 HTTP 连接例如 Socket 虚拟请求、单元测试中的模拟请求时Sails 通过 lib/router/req.js 中的buildRequest()工厂函数构造统一的req对象先创建基于 Node.jsstream.Transform的MockIncomingMessage实例lib/router/mock-req.js将method、url、headers写入其中随后以“与 Express 3 保持一致”为目标挂载req.get与req.header两者是同一函数的两个别名// Add .get() and .header() methods to match express 3 req.get req.header function (name) { switch (name name.toLowerCase()) { case referer: case referrer: return this.headers.referrer || this.headers.referer; default: return this.headers[name]; } };注意这里req.get与req.header指向同一个函数即两者完全等价可按习惯任选其一。另外值得留意的是lib/router/mock-req.js 只接受 String 类型的 header 值非字符串会自动做字符串化undefined会被丢弃因此在虚拟请求中req.get()拿到的结果一定是字符串或undefined。2. 真实 HTTP 请求对于来自真实 HTTP 服务器的请求req.get()由底层的 Express 中间件提供Sails 的 HTTP hook 基于 Express 构建。在 lib/hooks/request/metadata.js 中可以看到 Sails 对这一契约的强校验if (!_.isFunction(req.get)) { throw new Error(Consistency violation: At this point (in the request hook), req.get() should always exist as a function.); }这意味着在任何请求 hook 运行阶段req.get()都保证可用应用代码可以直接放心调用。3. 与req.headers的关系req.get(name)本质上是req.headers的便捷封装直接访问req.headers[content-type]要求你自行处理大小写与拼写差异而req.get(Content-Type)则屏蔽了这些细节且额外内置了 referrer/referer 的兼容逻辑。因此官方推荐在需要读取请求头时优先使用req.get()。四、Sails 内部的真实应用场景req.get()不是仅供应用开发者使用的 APISails 自身的核心 hook 也在大量依赖它理解这些用法有助于你在自己的代码中举一反三。1. 解析 Host 与 X-Forwarded-Hostlib/hooks/request/metadata.jsSails 在请求初始化阶段用req.get()读取X-Forwarded-Host与Host进而推导出req.port与req.baseUrlvar xForwardedHostHeader req.get(X-Forwarded-Host); var hostHeader req.get(Host); if (trustProxy xForwardedHostHeader) { host xForwardedHostHeader.split(/,\s*/)[0]; } else if (hostHeader) { host hostHeader; }这里的trustProxy来自sails.config.http.trustProxy或 Express 的trust proxy设置只有启用信任代理时才会优先使用X-Forwarded-Host这是部署在 Nginx、负载均衡等反向代理之后的常见配置。2. 判定wantsJSON与explicitlyAcceptsHTMLlib/hooks/request/qualifiers.jsreq.get(Accept)被用于判断客户端期望的响应格式var accept req.get(Accept) || ; req.explicitlyAcceptsHTML (accept.indexOf(html) ! -1); // ... req.wantsJSON req.wantsJSON || (req.is(json) req.get(Accept));这些标志直接影响 Sails 的响应协商行为例如错误页面是返回 JSON 还是 HTML也就是说你的请求头Accept会经由req.get()参与框架的响应决策链路。五、实战技巧与注意事项1. 在控制器 / 策略 / 中间件中读取请求头在任意控制器 action 或策略中req已经就绪可直接读取module.exports { friendlyName: 读取请求头示例, fn: async function (req, res) { // 读取常见的 User-Agent var ua req.get(User-Agent); // 读取自定义请求头如 X-API-Key var apiKey req.get(X-API-Key); // 读取来源页地址referrer / referer 均可 var referer req.get(referrer); return res.json({ ua: ua, apiKey: apiKey, referer: referer }); } };2. 处理不存在的请求头当请求中不存在指定 header 时req.get()返回undefined。建议在业务逻辑中做防御性处理var lang req.get(Accept-Language) || zh-CN;3. 大小写与拼写无需担心传入的字段名大小写随意req.get(accept-language)与req.get(Accept-Language)等价涉及来源页时referrer/referer 两种拼写通用无需区分。4. 读取 Cookie 与查询参数请使用专用 APIreq.get()只负责请求头。读取 Cookie 请用req.cookies或req.signedCookies读取 URL 查询串与请求体参数请用 req.param() /req.query/req.body不要用req.get()混用。5. 不要被请求头欺骗校验上游来源Referer与User-Agent等请求头均可由客户端伪造不要将其作为唯一的安全依据。涉及鉴权时应使用真正的认证机制Session、JWT 等与 Sails 策略Policies并参考 docs/concepts/Security/Security.md 中的安全实践。六、总结req.get()是 Sails 请求对象上最基础也最常用的方法之一用法简单req.get(header)一行代码即可读取任意请求头行为健壮大小写不敏感referrer/referer同义无需关心客户端拼写来源统一真实 HTTP 请求与 Socket 虚拟请求共享同一套 API配合req.get req.header的别名设计与 Express 3 生态完全兼容框架自身也在用Host 解析、wantsJSON判定等核心逻辑都建立在它之上。掌握req.get()是理解 Sails 请求生命周期docs/reference/req/req.md与编写可维护控制器代码的第一步。延伸阅读请求对象总览docs/reference/req/req.md请求头相关方法req.headers、req.accepts()虚拟请求构造源码lib/router/req.js、lib/router/mock-req.js请求 hook 源码lib/hooks/request/metadata.js、lib/hooks/request/qualifiers.js赞分享后端【免费下载链接】sailsRealtime MVC Framework for Node.js项目地址https://gitcode.com/gh_mirrors/sa/sails点击查看免费下载相关推荐NanUI高级功能揭秘消息桥接、子进程和自定义渲染的深度探索 NanUI高级功能揭秘消息桥接、子进程和自定义渲染的深度探索 NanUI是一个开源的.NET项目专为希望使用HTML、CSS和JavaScript创建Axios AxiosHeaders 深度解析大小写不敏感的请求头管理、默认头移除与 Unicode 值净化Axios AxiosHeaders 深度解析大小写不敏感的请求头管理、默认头移除与 Unicode 值净化 本篇技术指南基于 Axios 官方文档 docs网络后端前端SqlSugar 中实现 SQLite 列大小写不敏感排序的方法SqlSugar 中实现 SQLite 列大小写不敏感排序的方法 引言 在实际开发中我们经常需要对数据库中的字符串字段进行排序操作。然而SQLite 默认的后端数据库ORM创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考