首页 后端技术 正文
  • 本文约1406字,阅读需7分钟
  • 12
  • 0

Gin + go:embed 实现静态资源嵌入

摘要

如何嵌入资源文件 Go 在 1.16 版本增加了一个特性 go:embed,可以在编译时嵌入文件或者目录,我们可以使用这个命令实现资源文件的嵌入。 示例项目目录如下: ginweb ├── go.mod ├── go.sum ├── main.go // 主程序 └── web // 需要嵌入的资源文件 ├...

如何嵌入资源文件

Go 在 1.16 版本增加了一个特性 go:embed,可以在编译时嵌入文件或者目录,我们可以使用这个命令实现资源文件的嵌入。

示例项目目录如下:

ginweb
 ├── go.mod
 ├── go.sum
 ├── main.go            // 主程序
 └── web                // 需要嵌入的资源文件
     ├── index.html    // 静态资源文件
     └── photo.jpg    // 静态资源文件

例如通过 go:embed 将项目中的 web 目录下的所有文件进行嵌入,这时 WebDir 变量就是一个虚拟的文件系统,可以直接当作文件进行操作。

var (
    //go:embed web/*
    WebDir embed.FS
)

使用 HTTP 服务加载资源

// 通过 Gin 的 StaticFS() 方法,可以将嵌入的资源起一个 HTTP 服务,现在访问 2333 端口默认就会加载 /static/index.html 文件。

package main

import (
    "embed"
    "github.com/gin-gonic/gin"
    "io/fs"
    "net/http"
)

var (
    //go:embed web/*
    WebDir embed.FS
    App    *gin.Engine
)

func main() {
    App = gin.New()
    staticFp, _ := fs.Sub(WebDir, "web")
    // 起一个静态资源 HTTP 服务
    App.StaticFS("/static", http.FS(staticFp))
    // 这是一个接口
    App.GET("/api", func(context *gin.Context) {
        context.JSONP(http.StatusOK, gin.H{
            "code":    0,
            "message": "hi,dbkuaizi",
        })
    })
    App.Run(":2333")
}

利用 NoRoute 去掉 /static 目录

上面我们虽然实现了静态资源的加载,但为了区分 api 接口和静态资源,不得不多加一层 /static 静态资源目录,其实有更巧妙的方法免除掉这个目录。

我们可以利用 gin.NoRoute() 方法,这个方法的本意是当请求的接口不存在时,用于处理 404 相关的操作。我们可以在接口匹配失败后尝试加载静态资源,请求地址如下:

package main

import (
    "embed"
    "github.com/gin-gonic/gin"
    "io/fs"
    "net/http"
)

var (
    //go:embed web/*
    WebDir embed.FS
    App    *gin.Engine
)

func main() {
    App = gin.New()
    // 这是一个接口
    App.GET("/api", func(context *gin.Context) {
        context.JSONP(http.StatusOK, gin.H{
            "code":    0,
            "message": "hi,dbkuaizi",
        })
    })
    // 嵌入的 embed 就是一个文件系统,获取 web 目录下的资源文件
    staticFp, _ := fs.Sub(WebDir, "web")
    // 所有请求先匹配 api 路由,如果没匹配到就当作静态资源文件处理
    App.NoRoute(gin.WrapH(http.FileServer(http.FS(staticFp))))
    // 实现 api 端口、服务器端口共用一个
    App.Run(":2333")
}

在使用引用静态文件时,

将 Web 目录当作根目录来使用,例如:

<!doctype html>
<html lang="zh">
<head>
    <title>dbkuaizi.com</title>
</head>
<body>
    <h1>hi,dbkuaizi</h1>
        <img src="./photo.jpg" width="200px">
    </body>
</html>
    评论
    更换验证码
    友情链接