在Go,地图HandleFuncs中请求重新路由

时间:2018-07-08 14:37:37

标签: go gorequest

我想将路径名映射到位于其他位置的文件。但是,当我访问/path/c.txt而不是/a时,我的代码将服务/path/a.txt。我在做什么错了?

package main

import (
    "fmt"
    "net/http"
)

func main() {
    fileRoutes := map[string]string {
        "/a": "/path/a.txt",
        "/b": "/path/b.txt",
        "/c": "/path/c.txt",
    }

    for req, path := range fileRoutes {
        http.HandleFunc(req, func(w http.ResponseWriter, r *http.Request) {
            fmt.Printf("actual request: %v\n", r.URL.Path)
            fmt.Printf("registered request: %v\n", req)

            r.URL.Path = path

            fmt.Println(req)
            fmt.Println(path)

            // serveFile(w, r)
        })
    }

    http.ListenAndServe(":8004", nil)
}

此示例代码产生:

actual request: /a
registered request: /c
/c
/path/c.txt

谢谢!

2 个答案:

答案 0 :(得分:3)

问题在于,所有句柄函数都访问相同的reqpath,它们被设置为循环后循环的最后一个变量,分别为/c和{{ 1}}。

要解决此问题,请在/path/c.txt之前添加req,path := req,path

似乎很奇怪。它的作用是在循环范围内声明新的http.HandleFunc(...)req,这在每次迭代中都是新的,因此每个闭包都绑定到不同的值。

答案 1 :(得分:0)

另一种解决方案将是这里使用的解决方案(感谢我现在对答案的理解):https://github.com/golang/blog/blob/master/rewrite.go

path := fileRoutes[req] 之前 http.HandleFunc