将Express作为代理使用时如何获取自身服务端URL及子域名值
问题原因
你当前从req.headers.host拿到的是代理目标站(示例中的google.com),是HTTP代理的标准规范要求:客户端发起代理请求时,会将目标站点的域名放在Host请求头中,因此HTTP层默认拿不到代理服务自身的访问域名。
解决方案:从TLS层读取SNI字段
你使用的是HTTPS代理,客户端发起TLS握手时会携带SNI(Server Name Indication)扩展,里面明确写了要访问的代理服务域名,这个值存在于TLS套接字属性中,不会被HTTP层的请求头覆盖,可以直接读取。
修改后的完整代码如下:
import express from "express"; import proxy from "express-http-proxy"; const proxyApp = express(); proxyApp.use((req, res, next) => { // 读取TLS握手阶段携带的代理服务域名 const proxyServerDomain = req.socket.servername; // 按域名规则分割出子域名,可根据你的实际域名结构调整分割逻辑 const subdomain = proxyServerDomain.split('.')[0]; if (subdomain === "subdomainX") { next(); return; } res.send("Not authorized"); }); proxyApp.use( proxy( (req) => { return req.protocol + "://" + req.get("host"); }, { https: true, } ) ); proxyApp.listen(8000);
注意事项
- 该方案仅适用于HTTPS代理场景,如果你的代理服务是HTTP协议,可在代理服务前加一层Nginx反向代理,配置Nginx携带
X-Forwarded-Host请求头,同时在Express中开启trust proxy配置,就可以通过req.hostname拿到代理服务自身的域名。 - 如果你的域名是多级结构(比如
subdomainX.region.example.com),需要自行调整子域名分割逻辑。
内容的提问来源于stack exchange,提问作者Cup of Java
相关产品推荐
相关产品推荐

