首页>>后端>>Golang->Golang实践录:静态资源文件整合:web服务

Golang实践录:静态资源文件整合:web服务

时间:2023-12-01 本站 点击:0

本文在前面文章基础上,继续研究静态资源文件的整合,主要是在 web 服务器的整合。

基础

Golang 中的 web 服务框架有很多种,本文选取 gin 实现。gin 实现一个 web 服务仅需几行代码,十分方便。但为了适应更复杂的项目,还需要进行一些改进。 web 服务页面的文件,除了 html 外,还有 css、js、图片等文件,为方便管理,将后者放到 static 目录——与前面文章目录保持一致,将前者放到 templates 目录,使用 gin 的 html 模板进行渲染,而且 gin 也支持自定义模板文件,恰好能适合我们的场景。

实践

资源文件

本文使用到的资源文件如下:

$treestatic/static/|--css||--bootstrap.min.css||--font-awesome.min.css|`--main.css|--favicon.ico`--js|--bootstrap.min.js|--jquery-1.8.3.min.js|--jquery-2.0.0.min.js`--main.js2directories,8files$treetemplates/templates/|--about.html|--about.js|--index.html|--login.html|--login.js`--nav.js0directories,6files

通用方式

为方便对比,先给出通用的 gin 框架,主要代码如下:

//直接引用文件形式funcwebServerFile(){fmt.Println("gintest...")router:=gin.Default()//似乎这样做,templates下只能有文件,不能有目录router.LoadHTMLGlob("templates/*")//将真实目录做不同前缀,方便引用cssjs等文件//有些自实现的用html文件或js文件,用html前缀。router.StaticFS("/js",http.Dir("static/js"))router.StaticFS("/css",http.Dir("static/css"))router.StaticFS("/html",http.Dir("templates"))router.GET("/",HandleIndex)router.GET("/index",HandleIndex)router.GET("/about",HandleAbout)router.GET("/login",HandleLogin)router.Run(":8081")}

其中 LoadHTMLGlob 用于加载 html 模板文件,StaticFS 指定静态资源,有两个参数,第一个指定前缀名称(即在 html 或 js 文件中引用时使用的路径,第二个指定真实路径(相对于 web 程序所在目录)。GET 函数用于响应对应的页面,由于响应函数非本文重点,故简单列举如下:

funcHandleIndex(ctx*gin.Context){file:=path.Join(gPrefix,"index.html")ctx.HTML(http.StatusOK,file,gin.H{"title":"Mainwebsite",})}

注:gPrefix 将在下文提及。

整合方式

使用 bindata 方式,与上面示例没有本质区别,只是需要手动设置模板加载规则,指定静态资源文件方式也不同。主要代码如下:

//整合文件形式funcwebServerBindata(){fmt.Println("gintest.....")router:=gin.Default()t,err:=loadTemplate()iferr!=nil{panic(err)}router.SetHTMLTemplate(t)//下面指定的是静态资源文件,与响应get/post的地址无关系fsjs:=assetfs.AssetFS{Asset:bindata.Asset,AssetDir:bindata.AssetDir,AssetInfo:bindata.AssetInfo,Prefix:"static/js",Fallback:"index.html",}router.StaticFS("/js",&fsjs)fscss:=assetfs.AssetFS{Asset:bindata.Asset,AssetDir:bindata.AssetDir,AssetInfo:bindata.AssetInfo,Prefix:"static/css",Fallback:"index.html",}router.StaticFS("/css",&fscss)fshtml:=assetfs.AssetFS{Asset:bindata.Asset,AssetDir:bindata.AssetDir,AssetInfo:bindata.AssetInfo,Prefix:"templates",Fallback:"index.html",}router.StaticFS("/html",&fshtml)router.StaticFS("/favicon.ico",&fshtml)//人为添加前缀,因为前面loadTemplate加载的html路径包含有路径前缀,因此加上//如果手动删除,则此处不需要前缀//gPrefix="templates"router.GET("/",HandleIndex)router.GET("/index",HandleIndex)router.GET("/about",HandleAbout)router.GET("/login",HandleLogin)router.Run(":8081")}

自定义模板加载函数如下:

funcloadTemplate()(*template.Template,error){fmt.Println("loadmytemplate")t:=template.New("")filenames:=bindata.AssetNames()for_,name:=rangefilenames{if!strings.HasSuffix(name,".tmpl")&&!strings.HasSuffix(name,".html")&&!strings.HasSuffix(name,".css")&&!strings.HasSuffix(name,".js")&&!strings.HasSuffix(name,".ico"){continue}//fmt.Println("gothtmlfile:",name)content,err:=bindata.Asset(name)iferr!=nil{returnnil,err}t,err=t.New(name).Parse(string(content))iferr!=nil{returnnil,err}}returnt,nil}

由于在生成 bindata.go 时,指定了2处目录,而-prefix选项只能指定一个前缀,于是干脆不加该参数,因此,生成的代码中,前缀也会出现对应的目录,正因为这样,代码才使用了gPrefix = "templates"手动指定前缀。后来手动删除生成代码的前缀,命令如下:

sed-i's/templates///g'bindata/bindata.gosed-i's/static///g'bindata/bindata.go

两者关键代码对比如下图所示(注:左侧为未删除前缀的代码)。

笔者阅读 go-bindata-assetfs 代码尝试添加参数达到目的,未果,还是依照其机制实现。

参考

https://jaycechant.info/2020/go-bindata-golang-static-resources-embedding/

http://blog.hotsun168.com/index.php/archives/18/

1.16 版本新方法: https://www.flysnow.org/2021/02/28/golang-embed-for-web.html


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Golang/5849.html