亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

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

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

Go
MMTTMM 2022-05-18 14:17:00
當使用嵌套http.ServeMux來定義我的服務器的端點時,我遇到了這個問題:處理程序總是會以“301 永久移動”響應任何請求,即使 URL 路徑應該匹配。例子:package mainimport "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。
查看完整描述

3 回答

?
拉丁的傳說

TA貢獻1789條經驗 獲得超8個贊

為了讓 Firefox 中的測試更容易,我禁用了緩存。否則我將不得不手動清除緩存以獲得準確的結果。不過,在使用 Chrome 時,我似乎沒有遇到同樣的問題。

http://img1.sycdn.imooc.com//62848f7d00015a2a11950168.jpg

請記住,我是 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"))

}

我希望這在某種程度上有所幫助!干杯


查看完整回答
反對 回復 2022-05-18
?
慕桂英4014372

TA貢獻1871條經驗 獲得超13個贊

前幾天我正在處理這個問題。我認為ServeMux期望有根樹(以 開頭/),或者它將路徑解釋為主機名。


模式名稱固定,有根路徑,如“/favicon.ico”,或有根子樹,如“/images/”.... 模式可以選擇以主機名開頭,將匹配限制為僅該主機上的 URL。


我推測這ping被解釋為主機名,這會導致 servermux 的運行方式變得怪異。


在人們編寫的其他解決方案中,他們圍繞 的位置進行更改,/以使ping路線最終為/ping。


就個人而言,我不喜歡我必須/api/在一個地方和/api另一個地方寫作。在我的特殊情況下,我決定使用類似的東西:


root.Handle(createAPIEndpoints("/api/"))

...

func createAPIEndpoints(base string) (string, *http.ServeMux) {


    mux := http.NewServeMux()

    mux.HandleFunc(base+"ping", func(...){...})

    mux.HandleFunc(base+"another", func(...){...})


    // another buried servemux

    mux.Handle(createMoreEndpoints(base+"more/"))


    return base, mux

}

但是,如果您想用處理程序包裝處理程序(例如使用StripPrefix或其他類型的中間件,由于返回 2 個值,這不能很好地工作。


查看完整回答
反對 回復 2022-05-18
?
ITMISS

TA貢獻1871條經驗 獲得超8個贊

我遇到了類似的問題,但僅在您嘗試/在嵌套路由器下定義根路徑的情況下。


為了處理它,我重寫了我自己的 stripPefix() 方法,如下所示:


package main


import "net/http"


func main() {

    root := http.NewServeMux()

    api := http.NewServeMux()


    api.HandleFunc("/", myHandlerFunc)


    root.Handle("/api", stripPrefix("/api", api))


    http.ListenAndServe(":8080", root)

}


func myHandlerFunc(w http.ResponseWriter, r *http.Request) {

    w.Write([]byte("OK\n"))

}


// Modified version of http.StripPrefix()

func stripPrefix(prefix string, h http.Handler) http.Handler {

    if prefix == "" {

        return h

    }


    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        if p := strings.TrimPrefix(r.URL.Path, prefix); len(p) < len(r.URL.Path) {

            r2 := new(http.Request)

            *r2 = *r

            r2.URL = new(url.URL)

            *r2.URL = *r.URL

            if len(p) == 0 {

                r2.URL.Path = "/"

            } else {

                r2.URL.Path = p

            }

            h.ServeHTTP(w, r2)

        } else {

            http.NotFound(w, r)

        }

    })

}


查看完整回答
反對 回復 2022-05-18
  • 3 回答
  • 0 關注
  • 251 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號