You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Express.js结合隧道服务时,如何获取请求实际URL并实现HTTPS跳转?

解决Express+localtunnel/serveo下HTTP重定向HTTPS的无限循环问题

问题原因

localtunnel/serveo这类隧道服务本质是反向代理:客户端发起的HTTPS请求先到达隧道服务器,再由隧道服务器以HTTP协议转发到本地的Express服务。因此Express直接读取的req.protocol始终是http,无法识别客户端实际使用的HTTPS协议,导致每次都触发重定向,形成循环。

解决方案

反向代理会在转发请求时添加特殊请求头传递客户端原始请求信息,其中x-forwarded-proto字段记录了客户端实际使用的协议(http/https)。我们需要让Express信任这些代理头,从而正确获取客户端协议。

步骤1:配置Express信任代理

在Express初始化后添加以下配置,让Express信任反向代理的请求头:

app.set('trust proxy', true);

这个设置会让Express自动从x-forwarded-proto头中读取客户端的原始协议,此时req.protocol会返回客户端实际使用的协议(如https),而非本地的http。

步骤2:修改重定向逻辑

基于修正后的req.protocol,调整重定向代码:

const app = require("express")();

// 信任反向代理的请求头,确保req.protocol获取客户端真实协议
app.set('trust proxy', true);

app.get("/", function(req, res) {
  // 判断客户端是否用HTTP访问
  if (req.protocol === "http") {
    // 重定向到HTTPS版本,使用req.hostname获取隧道的主机名
    return res.redirect(301, `https://${req.hostname}${req.url}`);
  }
  return res.send("Hello!");
});

app.listen(8080);

(async () => {
  const localtunnel = require('localtunnel');
  const tunnel = await localtunnel({ port: 8080, subdomain: "example" });
  console.log(tunnel.url);
})();

备选方案:直接读取代理头(无需设置trust proxy)

如果你不想全局设置trust proxy,也可以直接读取x-forwarded-proto请求头判断客户端协议:

app.get("/", function(req, res) {
  // 优先取代理头中的协议, fallback到本地协议
  const clientProtocol = req.headers['x-forwarded-proto'] || req.protocol;
  
  if (clientProtocol === "http") {
    return res.redirect(301, `https://${req.hostname}${req.url}`);
  }
  return res.send("Hello!");
});

注意事项

  • 使用301永久重定向而非302临时重定向,更符合HTTPS强制跳转场景,也能让浏览器缓存重定向规则。
  • 主流隧道服务(localtunnel/serveo)均支持转发x-forwarded-proto头,无需额外配置。

内容的提问来源于stack exchange,提问作者Normal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:09:57