应使用c.Request.Host提取域名并手动比对,注意截取端口前的纯域名;重定向优先选302避免缓存问题;需用白名单控制、加return防循环;跨域跳转时Cookie不自动携带,建议透传token。

如何用 c.Request.Host 判断来源域名
Gin 中没有内置“按 Host 自动分流”的机制,必须手动提取并比对 c.Request.Host。它返回的是请求头里的 Host 字段(如 example.com:8080 或纯域名),注意不含协议,也不做 DNS 解析,只是原始字符串。
常见错误是直接用 c.Request.URL.Host——它可能为空或不准确,因为 URL 可能被反向代理改写;而 Host 头由客户端或前置代理(如 Nginx)设置,更可靠。
- 若部署在反向代理后(如 Nginx + Gin),确保代理配置了
proxy_set_header Host $host; -
c.Request.Host包含端口(如test.local:3000),比对前建议用strings.Split(c.Request.Host, ":")[0]截取纯域名 - 开发时用
localhost测试,但生产环境该值通常是真实域名,别硬编码localhost做判断
c.Redirect 的状态码选 302 还是 301?
绝大多数“按域名跳转”场景应使用 http.StatusFound(即 302),而不是 301。301 是永久重定向,浏览器和 CDN 会强缓存,一旦配错,用户后续访问可能永远绕不开错误跳转,排查成本极高。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 调试阶段一律用 302:改完代码重启服务即可生效,无需清浏览器缓存
- 只有确认某域名迁移已长期稳定(如
old-site.com → new-site.com),才考虑 301 - Gin 的
c.Redirect()不会自动加Location协议头,目标 URL 必须是完整路径(如/dashboard)或绝对 URL(如https://admin.example.com/login)
避免重定向循环的两个关键检查
当多个域名共用同一套 Gin 服务时,容易因条件覆盖不全导致无限跳转,比如 a.com 跳到 b.com,而 b.com 又跳回 a.com。
立即学习“go语言免费学习笔记(深入)”;
- 务必在重定向前加
return,否则后续逻辑仍会执行(Gin 不会自动终止 handler) - 用白名单而非黑名单思维:只对明确允许的域名放行,其余统一跳转,而不是“如果不是 A 就跳 B”——这样漏掉 C 域名就会出问题
- 示例安全写法:
host := strings.Split(c.Request.Host, ":")[0] switch host { case "admin.example.com": // 允许访问管理后台 case "user.example.com": c.Redirect(http.StatusFound, "/user/dashboard") return default: c.Redirect(http.StatusFound, "https://www.example.com/") return }
跨域重定向时 Cookie 和认证头会丢失
从 api.example.com 重定向到 app.example.com 属于跨子域跳转,浏览器默认不会携带原请求的 Cookie(除非后端显式设了 Domain=.example.com),前端 JS 也拿不到响应头里的 Set-Cookie。
- 如果跳转目的是传递登录态,不要依赖重定向带 Cookie,改用 token 参数透传(如
c.Redirect(http.StatusFound, "/login?token="+token)) - 绝对 URL 重定向(含协议)才能触发跨域;同域下仅路径跳转(如
/home)则 Cookie 保留 - 某些前端框架(如 Vue Router)会拦截 3xx 响应,导致重定向不生效——此时需后端返回 JSON 提示,由前端 JS 手动
window.location.href
Host 头的篡改,以及 301 缓存带来的“改了代码却没效果”问题。这两点不验证清楚,其他逻辑再严谨也没用。


















