【新手】关于go框架gin的静态托管和api同时使用报错的问题
gin框架,我想使用/,在打开网站的时候返回静态首页,使用其他比如/hello的时候返回接口,我是新鸟啊,开发的时候遇到了问题,求解大家,谢谢
如代码截图和注释,使用了静态/就不能用接口了,我百度了很久找不到原因
package mainimport "github.com/gin-gonic/gin"
func main() {
router := gin.Default()
// 单独使用下面的静态托管能在http://localhost:2019/看到正确的html
router.Static("/", "./www")
// 但是下面的接口就不能使用了,必须注释掉上面一句,下面接口才能使用
router.GET("/hello", func(c *gin.Context) {
c.String(200, `hello golang.`)
})
router.Run(":2019")
}
错误信息
求教,谢谢
回答:
router.Static("/", "./www")
其中的/相当于/*
,包含了/hello
建议为静态页面加个子目录如/web/
回答:
你可以理解为,这是 gin 中的限制,gin 中每个路由的规则是不能有交集的,比如这里的 /
和 /web
是有交集的,即 /web
也满足是 /
的情况。可以看看一个 github issue 中的关于问题的这个描述。
那这个问题该怎么解决呢?
我想到的是,静态页面 / 修改为 /static。如果是某些特殊的效果,可以在 nginx 反向代理之上做一层转化,将所有 / 指向 /static,nginx 的 location 规则还是比较丰富的。
说实话,我也不知道 gin 为什么这么做?或许是为了降低复杂度,降低出错的可能吧。通常,在用其他的 web 框架时,都是会根据 router 设置优先级的顺序决定启动那个路由。
回答:
结论: 两条路由注册的顺序换一下就好了。
原理: httprouter存在注册路由优先级问题,/*路由会包含后续注册的一切的路由,导致后续全部失效,而不存在优先级 常量>遍历>通配符的匹配效果,实际谁先注册谁优先级高,而gin就继承了httprouter的整个问题。
在源码中urlPattern := path.Join(relativePath, "/*filepath")
,join了路径,实践static注册路径为/*filepath.
// Static serves files from the given file system root.// Internally a http.FileServer is used, therefore http.NotFound is used instead
// of the Router's NotFound handler.
// To use the operating system's file system implementation,
// use :
// router.Static("/static", "/var/www")
func (group *RouterGroup) Static(relativePath, root string) IRoutes {
return group.StaticFS(relativePath, Dir(root, false))
}
// StaticFS works just like `Static()` but a custom `http.FileSystem` can be used instead.
// Gin by default user: gin.Dir()
func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem) IRoutes {
if strings.Contains(relativePath, ":") || strings.Contains(relativePath, "*") {
panic("URL parameters can not be used when serving a static folder")
}
handler := group.createStaticHandler(relativePath, fs)
urlPattern := path.Join(relativePath, "/*filepath")
// Register GET and HEAD handlers
group.GET(urlPattern, handler)
group.HEAD(urlPattern, handler)
return group.returnObj()
}
以上是 【新手】关于go框架gin的静态托管和api同时使用报错的问题 的全部内容, 来源链接: utcz.com/p/182530.html