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

发布于 2022-09-11 22:44:41 字数 665 浏览 37 评论 0

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")
}

错误信息

图片描述

求教,谢谢

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

素食主义者 2022-09-18 22:44:41

router.Static("/", "./www") 其中的/相当于/*,包含了/hello
建议为静态页面加个子目录如/web/

傾旎 2022-09-18 22:44:41

你可以理解为,这是 gin 中的限制,gin 中每个路由的规则是不能有交集的,比如这里的 //web 是有交集的,即 /web 也满足是 / 的情况。可以看看一个 github issue 中的关于问题的这个描述。

那这个问题该怎么解决呢?

我想到的是,静态页面 / 修改为 /static。如果是某些特殊的效果,可以在 nginx 反向代理之上做一层转化,将所有 / 指向 /static,nginx 的 location 规则还是比较丰富的。

说实话,我也不知道 gin 为什么这么做?或许是为了降低复杂度,降低出错的可能吧。通常,在用其他的 web 框架时,都是会根据 router 设置优先级的顺序决定启动那个路由。

何必那么矫情 2022-09-18 22:44:41

结论: 两条路由注册的顺序换一下就好了

原理: 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()
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文