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

如何用Golang net/http库实现https://www.*到https://*的重定向?

解决Golang net/http中HTTPS www域名重定向问题

你现在的问题很明确:已经处理了HTTP到HTTPS的重定向(包括带www的HTTP请求),但HTTPS的www域名请求没有被重定向——这是因为你的ListenAndServeTLS使用了nil作为Handler,直接用了默认的ServeMux,而这个Mux里没有处理www域名的重定向逻辑。

不用额外库的话,我们只需要给HTTPS请求也加一层前置检查就行,具体修改步骤如下:

1. 新增一个www重定向的包装Handler

这个Handler会先检查请求的Host是否包含www.,如果是就重定向到不带www的HTTPS地址,否则把请求交给后续的业务Handler处理:

import "strings"

func wwwRedirectHandler(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 用HasPrefix比Contains更精准,避免Host中间出现www的情况
        if strings.HasPrefix(r.Host, "www.") { 
            u := *r.URL
            // 移除Host中的www.前缀
            u.Host = strings.TrimPrefix(r.Host, "www.")
            u.Scheme = "https"
            // 使用301永久重定向,更利于SEO和浏览器缓存
            http.Redirect(w, r, u.String(), http.StatusMovedPermanently)
            return
        }
        // 不是www域名,继续处理原有请求
        next.ServeHTTP(w, r)
    })
}

2. 修改你的listenAndHandle函数

原来的代码直接把业务Handler注册到了默认ServeMux,现在我们需要创建一个自定义的ServeMux,把业务Handler注册进去,再用上面的包装Handler包裹后传给ListenAndServeTLS:

func listenAndHandle() {
    // 创建自定义的ServeMux,替代默认的http.DefaultServeMux
    mux := http.NewServeMux()
    mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
    mux.HandleFunc("/", handle.PageIndex)

    // 启动HTTP 80端口的重定向服务,这块逻辑可以保留
    go func() {
        if err := http.ListenAndServe(":80", http.HandlerFunc(redirectTLS)); err != nil {
            handle.Lv.Println("ListenAndServe error:", err)
        }
    }()

    // 用www重定向Handler包装我们的业务mux,然后传给HTTPS服务
    wrappedHandler := wwwRedirectHandler(mux)
    handle.Lv.Println(http.ListenAndServeTLS(database.Config.PORT, database.Config.TLScertfile, database.Config.TLSkeyfile, wrappedHandler))
}

3. 优化原有的redirectTLS函数(可选)

你原来的redirectTLS里对www的HTTP请求用了StatusFound(302临时重定向),而其他HTTP到HTTPS用了StatusMovedPermanently(301永久重定向),建议统一成301,因为域名重定向通常是永久的,这样浏览器会缓存重定向规则,提升后续请求效率:

func redirectTLS(w http.ResponseWriter, r *http.Request) {
    if strings.HasPrefix(r.Host, "www.") {
        u := *r.URL
        u.Host = strings.TrimPrefix(r.Host, "www.")
        u.Scheme = "https"
        http.Redirect(w, r, u.String(), http.StatusMovedPermanently)
        return
    }
    http.Redirect(w, r, database.Config.TLSurl+r.RequestURI, http.StatusMovedPermanently)
}

这样修改后,所有四种情况的请求都会被正确重定向到https://DOMAIN:

  • http://DOMAIN → https://DOMAIN
  • http://www.DOMAIN → https://DOMAIN
  • https://www.DOMAIN → https://DOMAIN

这样就能解决会话Cookie的问题了,因为所有请求最终都会落到同一个主域名下。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 15:02:59