英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论