Golang Gin embed static 静态文件嵌入

需求

Gin开发Web服务时, 编译生成的应用可能如下, 需提供static目录和web-app.exe给用户
如果将static文件夹到生成的exe中,分发单个EXE文件给用户使用,更加方便

# 改进前
├── static
│   └── js/jquery.min.js
│   ├── favicon.ico
│   ├── index.html
├── web-app.exe
# 改进后
├── web-app.exe (static内嵌进exe里)

改进思路

a). Gin文档 静态资源嵌入 方案

参考: https://learnku.com/docs/gin-gonic/1.7/examples-bind-single-binary-with-template/11403
需要使用额外工具go-assets,操作有点复杂,因此不考虑

b). Gin 自带方法

代码

package main
import (
	"embed"
	"net/http"
	"github.com/gin-gonic/gin"
)
//go:embed static/*
var fs embed.FS
func main() {
	r := gin.Default()
	r.StaticFS("/static", http.FS(fs))
}

效果

favicon.ico为例, 需要访问
http://localhost/static/static/favicon.ico
中间多了两个static, 而index.html中可能资源位置是
<link rel="icon" href="/static/favicon.ico">

exampe1

c). 改进

1. 自带http库做法

http.StripPrefix("/static", http.FileServer(http.FS(fs)))

2. 查看gin staticfs源码

看下大致调用函数名,可以看到大概是这样调用
http.FileServer(fs).ServeHTTP(c.Writer, c.Request)

func (group *RouterGroup) createStaticHandler(relativePath string, fs http.FileSystem) HandlerFunc {
	absolutePath := group.calculateAbsolutePath(relativePath)
	fileServer := http.StripPrefix(absolutePath, http.FileServer(fs))
	return func(c *Context) {
		........ 读取fs中文件,判断是否存在有权限等错误,省略
		fileServer.ServeHTTP(c.Writer, c.Request)
	}
}

3. 最终解决方案

package main
import (
	"embed"
	"net/http"
	"github.com/gin-gonic/gin"
)
//go:embed static/*
var fs embed.FS
func main() {
	r := gin.Default()
/*
查看staticfs方案中gin启动日志可以看到,staticfs实际注册了GET、HEAD
[GIN-debug] GET    /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
[GIN-debug] HEAD   /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
因此直接用r.Any
*/
	r.Any("/static/*filepath", func(c *gin.Context) {
		staticServer := http.FileServer(http.FS(fs))
		staticServer.ServeHTTP(c.Writer, c.Request)
	})
	r.Run("localhost:80")
}

查看效果达到预期
example2

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值