嵌套的 ServeMux 总是返回“301 Moved Permanently”

Pap*_*Bag 6 http go

当使用嵌套http.ServeMux来定义我的服务器的端点时,我遇到了这个问题:处理程序总是以“301 Moved Permanently”响应任何请求,即使 URL 路径应该匹配。

例子:

package main

import "net/http"

func main() {
    api := http.NewServeMux()
    api.HandleFunc("ping", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("pong\n"))
    })

    root := http.NewServeMux()
    root.Handle("/api/", http.StripPrefix("/api/", api))
    http.ListenAndServe(":8080", root)
}
Run Code Online (Sandbox Code Playgroud)

尝试访问时/api/ping,服务器重定向到/ping(当然,返回 404)。同样的事情发生在任何路由下/api/-/api/foo重定向到/foo.

我使用的是 Go 1.13 和 curl 7.58。

Mat*_*ich 5

编辑:为了使 Firefox 中的测试更容易,我禁用了缓存。否则我将不得不手动清除缓存才能获得准确的结果。不过,我在使用 Chrome 时似乎没有遇到同样的问题。

在此输入图像描述


请记住,我是 Go 新手,但这个问题让我发疯......我经历了与你完全相同的行为(显然)......

Go/http 似乎对模式的格式化方式很挑剔。

我搞砸了大约一个小时,终于能够使用以下代码获得一个工作示例:

// Working Code
package main

import "net/http"

func main() {
    root := http.NewServeMux()
    api := http.NewServeMux()

    api.HandleFunc("/ping", myHandlerFunc)

    root.Handle("/api/", http.StripPrefix("/api", api))

    http.ListenAndServe(":8080", root)
}

func myHandlerFunc(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("pong\n"))
}
Run Code Online (Sandbox Code Playgroud)

我尝试了尽可能多的不同配置(就正/斜杠而言),上面的代码是我可以让它工作的唯一方法。

具体参考:

// Leading forward slash on /ping
api.HandleFunc("/ping", myHandlerFunc)

// The first /api/ is surrounded in forward slashes,
// the second /api only contains a leading forward slash
root.Handle("/api/", http.StripPrefix("/api", api))
Run Code Online (Sandbox Code Playgroud)

将代码更改为此会导致 404...

// DOES NOT WORK!!
package main

import "net/http"

func main() {
    root := http.NewServeMux()
    api := http.NewServeMux()

    api.HandleFunc("/ping", myHandlerFunc)

    root.Handle("/api", http.StripPrefix("/api", api))

    http.ListenAndServe(":8080", root)
}

func myHandlerFunc(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("pong\n"))
}
Run Code Online (Sandbox Code Playgroud)

我希望这能以某种方式有所帮助!干杯