如何在 Golang 路由中将 URL 作为参数传递?

huangapple go评论89阅读模式
英文:

How do I pass a URL as a parameter in a Golang route?

问题

我正在尝试在Golang中将URL作为参数传递,但在我查看的所有教程中都没有找到解决方案。问题是,我只能得到缺少一个关键斜杠的URL。

我的处理程序如下所示:

router.HandleFunc("/new/{url}", createURL)

所以请求看起来像这样:

www.myapp.heroku.com/new/https://www.google.com

然而,我得到的URL缺少一个斜杠:

http:/www.google.com

我确定这可能与RFC3986有关,但是否有办法按原样传递URL?

英文:

I'm trying to pass a URL as a parameter in Golang, and I haven't been able to find a solution in all of the tutorials I've looked at. The problem is that I can only get the url to return minus a crucial forward slash.

My handler looks like this:

router.HandleFunc("/new/{url}", createURL)

So the request would look like:

www.myapp.heroku.com/new/https://www.google.com

However, the url that I results is missing a slash:

http:/www.google.com

I sure it's probably got something to do with RFC3986, but is there a way to pass in the url as it is?

答案1

得分: 2

阅读了另一个问题后,我明白你的意思了。在 URL 进入 gorilla/mux 之前,实现一种 URL 重写器。该函数的代码如下:

func Rewriter(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 简单的 URL 重写器。如果以 API 路径开头,则进行重写
        pathReq := r.RequestURI
        if strings.HasPrefix(pathReq, "/new/") {
            // 对于 go1.8 之前的版本,请使用 url.QueryEscape
            pe := url.PathEscape(strings.TrimLeft(pathReq, "/new/"))
            r.URL.Path = "/new/" + pe
            r.URL.RawQuery = ""
        }

        h.ServeHTTP(w, r)
    })
}

在启动 HTTP 服务器时,将 gorilla 路由器包装起来:

r := mux.NewRouter()

// ... 其他处理程序
r.HandleFunc("/new/{original-url}", NewHandler)

// 使用 Rewriter 包装 mux.Router
log.Fatal(http.ListenAndServe(":8080", Rewriter(r)))

然后在你的 URL shortener 处理程序中,可以使用以下代码提取原始 URL:

func NewHandler(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    ou := vars["original-url"]
    // 对于 go1.8 之前的版本,请使用 url.QueryUnascape
    originalURL, err := url.PathUnescape(ou)
    
    // ... 其他处理
}

在我看来,不建议像这样实现 URL shortener 服务,主要是因为错误地使用了 HTTP 动词。任何 GET 请求都不应该在服务器上产生副作用,例如不应该在数据库中创建记录等。

英文:

After reading the other question, I understand what do you mean. Implement a kind of URL re-writer before URL goes to gorilla/mux. The function will look like:

func Rewriter(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        //Simple URL rewriter. Rewrite if it's started with API path
        pathReq := r.RequestURI
        if strings.HasPrefix(pathReq, "/new/") {
            //Use url.QueryEscape for pre go1.8
            pe := url.PathEscape(strings.TrimLeft(pathReq, "/new/"))
            r.URL.Path = "/new/" + pe
            r.URL.RawQuery = ""
        }

        h.ServeHTTP(w, r)
    })
}

Wrap gorilla router when starting the http server:

r := mux.NewRouter()

// ... other handler
r.HandleFunc("/new/{original-url}", NewHandler)

//Wrap mux.Router using Rewriter
log.Fatal(http.ListenAndServe(":8080", Rewriter(r)))

Then in your URL shortener handler, the original URL can be extracted using the following code:

func NewHandler(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    ou := vars["original-url"]
    //Use url.QueryUnascape for pre go1.8
    originalURL, err := url.PathUnescape(ou)
    
    //... other processing
}

IMHO, implementing URL shortener service like this is not recommended, mainly due to incorrect use of HTTP verbs. Any GET request should not leave side effect in server e.g. no record creation in database, etc.

答案2

得分: 2

这种特定行为在Gorilla Mux中可以通过将SkipClean设置为true来更改。

router := mux.NewRouter()
router.SkipClean(true)
router.HandleFunc("/new/", index)
router.HandleFunc("/", index)
http.ListenAndServe(":"+port, router)

相关文档可以在这里找到。

英文:

This particular behavior in Gorilla Mux can be changed by setting SkipClean to true.

router := mux.NewRouter()
router.SkipClean(true)
router.HandleFunc("/new/", index)
router.HandleFunc("/", index)
http.ListenAndServe(":"+port, router)

The relevant documentation can be found here.

huangapple
  • 本文由 发表于 2017年4月26日 21:30:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/43635701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定