将http.NewServeMux放入http.NewServeMux

ray*_*ray 0 http go

这是我的代码.我想把mux1作为子路由器放入mux.Handle.接下来,我运行代码.我可以访问路径/索引但我无法访问path/index/sub1.我不知道为什么我可以访问/索引但我不能访问/ index/sub1?

package main

import (
    "io"
    "net/http"
)

func main() {
    mux1 := http.NewServeMux()
    mux1.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "sub index")
    })
    mux1.HandleFunc("/sub1", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "sub 1")
    })

    mux := http.NewServeMux()
    mux.Handle("/index", mux1)

    http.ListenAndServe(":8000", mux)
}
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 6

您的示例不起作用,因为您使用/index路径注册"外部"处理程序,这是一个单独的路径(因为它不以斜杠结束/)而不是一个有根的子树(即,所有路径都以/index/)开头.这记录在http.ServeMux:

模式名称固定,带根的路径,如"/favicon.ico",或带根的子树,如"/ images /"(请注意尾部斜杠).较长的模式优先于较短的模式,因此如果有"/ images /"和"/ images/thumbnails /"注册的处理程序,后面的处理程序将被调用以开始"/ images/thumbnails /"的路径和前者将收到"/ images /"子树中任何其他路径的请求.

而且因为"子路由器"不会看到类似路径"/""/sub1"用于注册处理程序的路径,而是完整路径,即:"/index/""/index/sub1".

那么主路由器应该做的是"剥离" "/index"前缀,这是它注册的路径(没有尾部斜杠).幸运的是,标准的lib有一个现成的解决方案:http.StripPrefix().

所以工作解决方案:

mux1 := http.NewServeMux()
mux1.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "sub index")
})
mux1.HandleFunc("/sub1", func(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "sub 1")
})

mux := http.NewServeMux()
mux.Handle("/index/", http.StripPrefix("/index", mux1))

http.ListenAndServe(":8000", mux)
Run Code Online (Sandbox Code Playgroud)

测试它:

  • 网址:http://localhost:8000/index/
    回复:sub index

  • 网址:http://localhost:8000/index/sub1
    回复:sub 1