“go-bindata-assetfs”包的灵活使用
前面我们讲述了如何基于“go-bindata-assetfs”开源工具包将html/js/css静态文件打包到Go程序中,形成一个一体化Web服务程序(点此查看)。解决方案最核心的一句代码如下:
//静态请求,由AssetFS统一处理。
http.Handle("/", http.FileServer(assetFS()))
我们知道,如果需要对路由做更加灵活的处理,需要使用http.HandleFunc方法。那么上述代码意味着所有访问"/"路径下,未经其他路由处理过的路径都将被“assetfs”处理。这种方式在一些需要动态解析的场景下会存在比较麻烦的问题。
举例说明,在某种场景下我们虽然需要直接显示html文件,但是又必须在html回送给客户端前对其进行解析,加入动态查询的数据(如基于“template”包来进行模版渲染的伪静态文件)。这个时候,我们需要将“assetfs”提供给我们的数据结构进行灵活使用,先获取到html等静态文件的内容,把它当作模板进行解析,然后再输出到客户端。
下面将给出相应的解决方案,可以趁此机会,更好更细节的理解“assetfs”的工作原理。核心代码如下:
fs := assetFS()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
if path == "/" || strings.Contains(path, ".html") {
//根目录默认显示首页。
if path == "/" {
path = "/index.html"
}
data, _ := fs.Asset("pages" + path)
html := string(data)
//这里可以对html页面数据进行处理。
//...
w.Header().Add("Content-Type", "text/html; charset=UTF-8")
w.Write([]byte(html))
} else {
//其他处理。
//...
}
})
示例中,fs.Asset方法,作用是根据文件路径获取到该文件内容的字节数组。有一点需要注意的是,传入的文件路径必须带有文件编译前的前缀,如某“aaa.html”文件编译时,所在的解决方案路径为“xxx/yyy/”,VSCode终端中运行的是“go-bindata-assetfs xxx/yyy/...”,那么最终在使用fs.Asset方法获取文件内容字节数组时,应使用如下调用格式:
fs.Asset("xxx/yyy/aaa.html")
否则将无法获取到真实的数据。