http - 嵌套的 ServeMux 总是返回 "301 Moved Permanently"

标签 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)
}

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

我使用的是 Go 1.13 和 curl 7.58。

最佳答案

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

enter image description here

请记住,我是 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"))
}

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

具体指:

// 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))

将代码更改为此会导致 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"))
}

我希望这在某种程度上有所帮助!干杯

关于http - 嵌套的 ServeMux 总是返回 "301 Moved Permanently",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60344955/

相关文章:

apache - 如何为同一域但不同的上下文路径设置 2 个不同的 Web/应用程序服务器?

java - 当请求 Content-Type 为 gzip 时,Jetty 响应 400 Bad Request

string - golang 将 os.ModePerm 转换为字符串

go - 为什么这个程序产生输出

linux - 将 http access.log 重定向到 linux 中的远程服务器

wcf - HTTP 无法注册 URL ... 因为 TCP 端口 ... 正在被另一个应用程序使用

asp.net - 输出特定的 HTTP header

go - chan bool 是如何让 goroutine 等待的?

go - 在 Golang 中写入缓冲区的开头?

algorithm - Go:用于字符串比较的多项式指纹