go-bindata - embed combine des fichiers statiques intégrés pour empaqueter des binaires exécutables.
## intégrer intégrer des fichiers statiques dans des fichiers binaires exécutables
# Installer go-bindata
go get -u github.com/jteeuwen/go-bindata/...
#Package des fichiers statiques
go-bindata web/...
Après avoir exécuté cette commande, le fichier bindata.go sera généré dans le répertoire du projet. Les fichiers modèles de l'exemple de commande se trouvent tous dans le répertoire Web du projet.
# Utilisez embed pour enregistrer l'exemple de document modèle.
https://github.com/kataras/iris/blob/main/_examples/view/embedding-templates-into-app/main.go
https://github.com/kataras/iris/blob/main/_examples/view/embedding-templates-into-app/main.go
Exemple de code :
package main
import (
"embed"
"github.com/kataras/iris/v12"
)
//go:embed embedded/*
var embeddedFS embed.FS
func main() {
app := iris.New()
tmpl := iris.HTML(embeddedFS, ".html").RootDir("embedded/templates")
tmpl.Layout("layouts/layout.html")
tmpl.AddFunc("greet", func(s string) string {
return "Greetings " + s + "!"
})
app.RegisterView(tmpl)
app.Get("/", func(ctx iris.Context) {
if err := ctx.View("page1.html"); err != nil {
ctx.HTML("<h3>%s</h3>", err.Error())
return
}
})
// remove the layout for a specific route
app.Get("/nolayout", func(ctx iris.Context) {
ctx.ViewLayout(iris.NoLayout)
if err := ctx.View("page1.html"); err != nil {
ctx.HTML("<h3>%s</h3>", err.Error())
return
}
})
// set a layout for a party, .Layout should be BEFORE any Get or other Handle party's method
my := app.Party("/my").Layout("layouts/mylayout.html")
{ // both of these will use the layouts/mylayout.html as their layout.
my.Get("/", func(ctx iris.Context) {
if err := ctx.View("page1.html"); err != nil {
ctx.HTML("<h3>%s</h3>", err.Error())
return
}
})
my.Get("/other", func(ctx iris.Context) {
if err := ctx.View("page1.html"); err != nil {
ctx.HTML("<h3>%s</h3>", err.Error())
return
}
})
}
// http://localhost:8080
// http://localhost:8080/nolayout
// http://localhost:8080/my
// http://localhost:8080/my/other
app.Listen(":8080")
}
Projet main.py :
package main
import (
"embed"
"fmt"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/logger"
"github.com/kataras/iris/v12/mvc"
"runtime"
"vulnlistexport/conf"
"vulnlistexport/utils"
"vulnlistexport/web/controllers"
)
//go:embed web/*
var embeddedFS embed.FS
func getPortFromCommandLine() string {
//if len(os.Args) < 2 {
// // 如果命令行参数不足,则使用默认的端口号
// return conf.SysConfMap["port"]
//}
//
使用命令行参数中的第一个参数作为新的端口号
//port := os.Args[1]
//fmt.Println("Using port:", port)
port := conf.SysConfMap["port"]
confPort := conf.OutSysConfMap["port"]
if confPort != "" {
port = confPort
}
return port
}
func CheckAuth(ctx iris.Context) {
noCheckPath := []string{"/login", "/", "/plogin"}
if !utils.InSlice(ctx.Path(), noCheckPath) {
//token := ctx.GetHeader("Authorization")
token := ctx.GetCookie("token")
if token != conf.SysConfMap["password"]+conf.SysConfMap["username"] {
// 未登录,重定向至登录页
ctx.Redirect("/login")
return
}
}
// 用户已登录,继续执行后续处理程序
ctx.Next()
}
func main() {
//1.创建Iris 框架
app := iris.New()
//2.设置debug模式
app.Logger().SetLevel("error")
// 同时写文件日志与控制台日志
//app.Logger().SetOutput(io.MultiWriter(func() *os.File {
// //创建日志目录
// dirName := "log/" + time.Now().Format("2006/01")
// os.MkdirAll(dirName, os.ModePerm)
//
// today := time.Now().Format(conf.SysTimeformShort)
// filename := dirName + "/" + today + ".log"
// f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
// if err != nil {
// panic(err)
// }
// return f
//}(), os.Stdout))
//设置记录日志的格式
requestLogger := logger.New(logger.Config{
// Status displays status code
Status: true,
// IP displays request's remote address
IP: true,
// Method displays the http method
Method: true,
// Path displays the request path
Path: true,
// Query appends the url query to the Path.
Query: true,
// if !empty then its contents derives from `ctx.Values().Get("logger_message")
// will be added to the logs.
MessageContextKeys: []string{"logger_message"},
// if !empty then its contents derives from `ctx.GetHeader("User-Agent")
MessageHeaderKeys: []string{"User-Agent"},
})
app.Use(requestLogger)
//全局错误捕获
customRecover := func(ctx iris.Context) {
defer func() {
if err := recover(); err != nil {
if ctx.IsStopped() {
return
}
var stacktrace string
for i := 1; ; i++ {
_, f, l, got := runtime.Caller(i)
if !got {
break
}
stacktrace += fmt.Sprintf("%s:%d\n", f, l)
}
errMsg := fmt.Sprintf("错误信息: %s", err)
// when stack finishes
logMessage := fmt.Sprintf("从错误中回复:('%s')\n", ctx.HandlerName())
logMessage += errMsg + "\n"
logMessage += fmt.Sprintf("\n%s", stacktrace)
// 打印错误日志
ctx.Application().Logger().Warn(logMessage)
// 返回错误信息
ctx.JSON(errMsg)
ctx.StatusCode(500)
ctx.StopExecution()
}
}()
ctx.Next()
}
app.Use(customRecover)
//3.注册静态文件
app.HandleDir("/content", "./web/content")
// 创建一个 HTML 视图引擎对象,模板文件存放在 ./web/views 目录中,并且模板文件的后缀名是 .html
//tmpl := iris.HTML("./web/views", ".html")
tmpl := iris.HTML(embeddedFS, ".html").RootDir("web/views") // web/views目录下是html文件
// 注册一个自定义模板函数
tmpl.AddFunc("add", func(a, b int) int {
return a + b
})
//4.注册模版
app.RegisterView(tmpl)
//其它初始化操作,比如数据库,seesion初始化 todo
// 全局校验用户身份中间件
app.Use(CheckAuth)
//5.注册控制路由
//mvc.New(app.Party("/book")).Handle(new(controllers.BookController))
//mvc.New(app.Party("/demo")).Handle(new(controllers.DemoController))
mvc.New(app.Party("/")).Handle(new(controllers.RedirectController))
mvc.New(app.Party("/login")).Handle(new(controllers.LoginController))
mvc.New(app.Party("/plogin")).Handle(new(controllers.PLoginController))
mvc.New(app.Party("/tasks")).Handle(new(controllers.TaskController))
mvc.New(app.Party("/logout")).Handle(new(controllers.LogoutController))
//6.启动服务
app.Run(
// 启动服务在端口8082
//iris.Addr(conf.SysConfMap["domain"]+":"+conf.SysConfMap["port"]),
iris.Addr(conf.SysConfMap["domain"]+":"+getPortFromCommandLine()),
// 启动时禁止检测框架版本差异
//iris.WithoutVersionChecker,
//忽略服务器错误
iris.WithoutServerError(iris.ErrServerClosed),
//让程序自身尽可能的优化
iris.WithOptimizations,
iris.WithCharset("UTF-8"), // 国际化
)
}