【问题标题】:go 1.16: how to use strip prefix in go:embedgo 1.16:如何在 go:embed 中使用带前缀
【发布时间】:2021-05-22 06:46:09
【问题描述】:

我有一个使用VueJS 提供Web 界面的go 项目。在构建项目时,我首先使用npm run build 编译前端代码,该代码在我的项目目录的gui/dist 下生成。然后我使用这段代码来提供静态内容:

//go:embed gui/dist/*
var dist embed.FS

gui := http.FileServer(http.FS(dist))
http.Handle("/", gui)
http.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
    msg := fmt.Sprintf("TODO: %s", r.URL)
    http.Error(w, msg, http.StatusNotImplemented)
})

svr := http.Server{
    Addr:         fmt.Sprintf(":%v", cf.HTTPPort),
    ReadTimeout:  time.Minute,
    WriteTimeout: time.Minute,
}
assert(svr.ListenAndServe())

问题是,在浏览器中打开网站时,它显示了一个浏览文件界面,即以gui开头,然后进入dist,然后显示index.html文件,这是一个空白页面,因为它需要文件比如/css/...,而go web服务器在/gui/dist/css/...提供服务。

我尝试使用http.StripPrefix(),但显然它不是为了处理这种情况,或者我没有正确使用它:

http.Handle("/", http.StripPrefix("/gui/dist", gui))

它生成了一个404 page not found

【问题讨论】:

  • 它不起作用,因为你想要StripPrefix()相反:你想要请求/index.html,你想要gui/dist/index.html 服务。最简单的方法是提供gui/dist 文件夹而不是dist fs,请参阅下面@wasmup 的答案。

标签: go embed


【解决方案1】:

你可以使用fs.Sub(dist, "gui/dist") (docs),试试看:

package main

import (
    "embed"
    "fmt"
    "io/fs"
    "log"
    "net/http"
)

func main() {
    http.Handle("/", http.FileServer(getFileSystem()))
    http.HandleFunc("/api/", api)
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal(err)
    }
}

func getFileSystem() http.FileSystem {
    fsys, err := fs.Sub(dist, "gui/dist")
    if err != nil {
        log.Fatal(err)
    }
    return http.FS(fsys)
}
func api(w http.ResponseWriter, r *http.Request) {
    msg := fmt.Sprintf("TODO: %s", r.URL)
    http.Error(w, msg, http.StatusNotImplemented)
}

//go:embed gui/dist/*
var dist embed.FS

【讨论】:

    猜你喜欢
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多