go - 如何从除 Gin 中的一个路由之外的所有路由提供静态文件?
问题描述
正如标题所说,考虑一个 Gin 路由器,我想在其中提供来自除一个之外的所有路由的静态文件。假设这条路线是/api
. 第一次尝试可能如下所示:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.StaticFS("/", gin.Dir("static", false))
r.GET("/api/v1/foo", func(c *gin.Context) { c.JSON(200, gin.H{"foo": true}) })
r.Run(":9955")
}
引擎盖下的RouterGroup.StaticFS
(Static
也是)使用通配符路径参数连接相对路径:path.Join(relativePath, "/*filepath")
。什么时候relativePath
是根路径/
,它会恐慌:
恐慌:新路径“/api/v1/foo”中的“/api/v1/foo”与现有前缀“/*filepath”中的现有通配符“/*filepath”冲突
这是由于 Gin 的 http 路由器实现:路由匹配路径 prefix,因此 root 上的通配符将与所有其他路由冲突。可以在此处找到有关此行为的更多详细信息——这是提出此问题的地方。
另一种可能的解决方案是为静态文件路由添加前缀,这样它就不会与/api
:
r.StaticFS("/static", gin.Dir("static", false))
但这也不允许我从根目录提供资产。如何在根目录上使用通配符或等效项,并且仍然匹配一个特定路径?
解决方案
一种解决方案是在 root 上仅设置一个通配符路径参数,并使用顶级处理程序来检查路径。根据路径前缀,您将上下文重新输入到第二个路由器中Engine.HandleContext
:
func main() {
apiEngine := gin.New()
apiG := apiEngine.Group("/api")
{
apiG.GET("/foo", func(c *gin.Context) { c.JSON(200, gin.H{"foo": true})})
apiG.GET("/bar", func(c *gin.Context) { c.JSON(200, gin.H{"bar": true})})
}
r := gin.New()
r.GET("/*any", func(c *gin.Context) {
path := c.Param("any")
if strings.HasPrefix(path, "/api") {
apiEngine.HandleContext(c)
} else {
assetHandler(c)
}
})
r.Run(":9955")
}
在此示例中,辅助引擎apiEngine
仅用于以通常的方式声明路由,例如组和方法处理程序。你不运行它。相反,您HandleContext
在检查主通配符处理程序上的路径前缀后将 Gin 上下文传递给它。
在此示例中,所有方法都是GET
. 资产通常由 GET 提供,但如果您需要在辅助引擎中处理更多 http 方法,请将主处理程序声明为Any
. 就像是:
r := gin.New()
// allows any http method
r.Any("/*any", func(c *gin.Context) {
path := c.Param("any")
if strings.HasPrefix(path, "/api") {
apiEngine.HandleContext(c) // on this you can declare POST, PUT, etc.
// sanity check
} else if c.Request.Method == http.MethodGet {
assetHandler(c)
}
})
r.Run(":9955")
推荐阅读
- tensorflow - 为什么在 conda 虚拟环境中使用 pip 会产生全局效果?
- kotlin - Ktor 客户端身份验证功能不发送授权标头
- javascript - 找不到与 @angular-devkit/build-angular@0.901.1 匹配的版本
- python - 在 Windows 中安装 Python-saml 包时出错
- angular - angular2材料设计如何从dataSource动态填充mat-card?
- java - 如何通过 servlet 提供批量文件以供下载?
- linux - 在 ubuntu16.04 上编译 opencv3.2.0 失败
- matlab - 在matlab中编写计算悬臂梁弯矩的脚本
- azure-active-directory - CAS Central Authentication Service 可以访问google、office365
- javascript - 如何在带有树枝元素的外部文件中使用 javascript 代码?