如何用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
相关产品推荐
相关产品推荐

