处理完 GET 请求后,我想将用户重定向到由我的应用程序处理的新 URL,该应用程序会显示结果。
在 gin 文档中 我发现了两种不同的方法来做到这一点。一种是使用gin的
redirect()
功能,另一种是使用它的routerHandleContext()
功能。引用的文档说 redirect()
应该用于 POST 请求或 GET 请求,但随后又说 HandleContext()
应该用于“路由器”重定向。我不确定我是否完全理解使用其中之一的含义。
上面引用的文档中给出的第一个用例是:
r.GET("/test", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
})
这里似乎不同的是,重定向到一个外部 URL,远离我的应用程序本身。第二个用例被描述为“路由器重定向”,是:
r.GET("/test", func(c *gin.Context) {
c.Request.URL.Path = "/test2"
r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {
c.JSON(200, gin.H{"hello": "world"})
})
因此,如果重定向的 URL 是我的应用程序处理的路径,这似乎是必需的。
但这与其他 URL 一样。那么为什么不直接使用
c.redirect()
进行路由器重定向呢?
直观上来说,这是显而易见的事情。但我怀疑它会产生意想不到的行为(或者至少是我个人没有预料到的行为)
使用
c.redirect()
进行路由器重定向有什么问题,它和 router.HandleContext()
有什么区别?
HandleContext()
执行客户端永远不会注意到的 内部重定向,而 Redirect()
实际上向 Http 客户端发送响应,通知它资源已更改。
我认为通过观察浏览器的开发工具可以最好地说明这一点。
HandleContext()
:
正如您所看到的,这里客户端甚至没有注意到请求在内部被重定向到另一个处理程序。
Redirect()
:
这里客户端被迫发出两个请求来获取实际资源。另请注意,URL 栏现在显示重定向请求的 URL。
显然发出两个请求会导致性能变差,这就是为什么内部重定向应首选
router.HandleContext()
。
如果你想测试一下自己,这里是代码:
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// Switch the uncommented block in order to see the effect of HandleContext.
/* r.GET("/test", func(c *gin.Context) {
c.Request.URL.Path = "/test2"
r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {
c.JSON(200, gin.H{"hello": "world"})
}) */
r.GET("/test", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "/test2")
})
r.GET("/test2", func(c *gin.Context) {
c.JSON(200, gin.H{"hello": "world"})
})
r.Run()
}