【新手】关于go框架gin的静态托管和api同时使用报错的问题

gin框架,我想使用/,在打开网站的时候返回静态首页,使用其他比如/hello的时候返回接口,我是新鸟啊,开发的时候遇到了问题,求解大家,谢谢

图片描述

如代码截图和注释,使用了静态/就不能用接口了,我百度了很久找不到原因

package main

import "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

回到顶部