ctx.Redirect是最直接的HTTP重定向方式,底层使用302(默认)或301等状态码,需配合ctx.StopExecution()防止后续执行,支持相对路径与完整URL,但不适用于跨根域名跳转。

ctx.Redirect 是最直接的路径跳转方式
用 ctx.Redirect 可以跳转到任意路径或完整 URL,它底层调用的是 HTTP 301/302 状态码。默认行为是 302(临时重定向),适合登录后跳转、表单提交后防重复提交等场景。
-
ctx.Redirect("/dashboard", iris.StatusMovedPermanently)发送 301,适合 SEO 固定路径迁移,浏览器和爬虫会缓存该跳转 -
ctx.Redirect("https://example.com/home", iris.StatusFound)支持跨域完整 URL,但注意:跳转本身不受 CORS 限制,后续 JS 脚本可能因跨域被拦截 - 目标 URL 若为相对路径(如
"/login"),Iris 会自动补全当前请求的协议 + 主机 + 端口;若为绝对 URL,则完全按你写的发出去 - 务必在调用
ctx.Redirect后加ctx.StopExecution(),否则后续 handler 仍会执行,可能导致 panic 或双响应
SubdomainRedirect 专用于子域名间跳转
想把 mydomain.com 全量跳到 www.mydomain.com?不能靠 ctx.Redirect,得用 app.SubdomainRedirect。它不是对某个请求做响应,而是在路由层统一拦截并改写 Host 头。
- 必须先注册
www子域名路由:www := app.Subdomain("www"),再调用app.SubdomainRedirect(app, www),顺序反了会 panic - 本地测试需改
/etc/hosts(macOS/Linux)或C:\Windows\System32\drivers\etc\hosts(Windows),添加两行:127.0.0.1 mydomain.com和127.0.0.1 www.mydomain.com - 这个机制只处理 HTTP 请求;HTTPS 下若没配 TLS 证书,浏览器会先报证书错误,根本不会触发重定向
- 不支持跳转到不同根域名(比如
mydomain.com → other.com),仅限同一主域下的子域名映射
别在中间件里无条件 redirect
常见错误是给一个 Party 加中间件,以为所有子路径都会跳转:
- 错例:
oldGroup := app.Party("/old"); oldGroup.Use(func(ctx iris.Context) { ctx.Redirect("/new") })—— 这样访问/old/users会 404,因为没注册任何实际 handler - 正确做法是显式注册路由:
app.Get("/old", func(ctx iris.Context) { ctx.Redirect("/new") }),或者用正则匹配批量处理:app.Any("/{path:path}", func(ctx iris.Context) { if strings.HasPrefix(ctx.Path(), "/old/") { ctx.Redirect(strings.Replace(ctx.Path(), "/old/", "/new/", 1), iris.StatusMovedPermanently); ctx.StopExecution(); return } }) - 如果要用中间件,必须配合
ctx.Path()做路径判断,并且始终记得ctx.StopExecution()
301 和 302 的选择影响真实行为
状态码选错会导致缓存污染或调试困难:
- 用
iris.StatusMovedPermanently(301)后,浏览器会永久记住跳转,即使你后来删掉重定向逻辑,本地仍可能跳转——清浏览器缓存或换隐身窗口验证 -
iris.StatusFound(302)更安全,适合开发期、A/B 测试或临时维护页,但要注意某些 CDN 或代理可能不严格遵守 302 缓存策略 - 不要混用:比如在 HTTPS 站点里跳转到 HTTP 地址(
ctx.Redirect("http://example.com", ...)),现代浏览器会拒绝或降级,应保持协议一致
SubdomainRedirect 和 ctx.Redirect 的适用边界、StopExecution 的调用时机、以及 301/302 对客户端的实际影响,这三点最容易被忽略。


















