Golang中无法调用embed文件的问题如何解决

Golang中无法调用embed文件的问题如何解决 我按如下方式嵌入CSS和JS文件:

package resources

import (
	"embed"
)

// WebUI是我们来自onsen ui的静态web ui。
//go:embed public/onsen
var WebUI embed.FS

// Views是我们的静态web服务器布局、包含动态内容的视图以及作为静态视图的部分内容。
//go:embed templates/layouts templates/views templates/partials
var Views embed.FS

并尝试在我的主函数中将这个WebUI定义为static文件夹:

package main

import (
    "fmt"
    "log"
    "html/template"
	"net/http"
	"onsen/resources"
)

var view *template.Template
var err error

func init() {
	fmt.Println("Starting up.")
	view = template.Must(template.ParseFS(resources.Views, "templates/layouts/*.html", "templates/views/*.html", "templates/partials/*.html"))

	if err != nil {
		log.Fatal("Error loading templates:" + err.Error())
	}
}

func main() {
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(resources.WebUI))))
	//http.Handle("/static/", http.FileServer(http.FS(resources.WebUI)))

    http.HandleFunc("/index", index)
    server := http.Server{
		Addr: "127.0.0.1:8070",
	}
    server.ListenAndServe()
}

func index(w http.ResponseWriter, r *http.Request) {
	err = view.ExecuteTemplate(w, "index.html", nil)
	if err != nil {
		log.Fatalln(err)
	}
}

文件夹结构如下所示:

enter image description here

但在运行时,我遇到了以下错误:

enter image description here

CSS files: Refused to apply style from 'http://127.0.0.1:8070/static/css/onsenui.css' because its MIME type ('text/plain') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

JS files: Failed to load resource: the server responded with a status of 404 (Not Found)

更多关于Golang中无法调用embed文件的问题如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中无法调用embed文件的问题如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题出在文件服务器处理嵌入文件系统时的路径配置上。//go:embed public/onsenpublic/onsen 目录嵌入到 WebUI 变量中,但文件服务器访问的是该目录下的内容。

以下是修正后的代码:

package main

import (
    "fmt"
    "log"
    "html/template"
    "net/http"
    "onsen/resources"
)

var view *template.Template

func init() {
    fmt.Println("Starting up.")
    view = template.Must(template.ParseFS(resources.Views, 
        "templates/layouts/*.html", 
        "templates/views/*.html", 
        "templates/partials/*.html"))
}

func main() {
    // 修正1:使用正确的文件系统子目录
    webuiFS := http.FS(resources.WebUI)
    
    // 修正2:正确配置静态文件路径
    http.Handle("/static/", 
        http.StripPrefix("/static/", 
            http.FileServer(webuiFS)))

    http.HandleFunc("/index", index)
    
    server := http.Server{
        Addr: "127.0.0.1:8070",
    }
    
    fmt.Println("Server starting on http://127.0.0.1:8070")
    log.Fatal(server.ListenAndServe())
}

func index(w http.ResponseWriter, r *http.Request) {
    err := view.ExecuteTemplate(w, "index.html", nil)
    if err != nil {
        log.Println("Template error:", err)
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

关键修正点:

  1. 路径问题//go:embed public/onsen 将整个 public/onsen 目录嵌入。当访问 /static/css/onsenui.css 时,服务器会在嵌入的 public/onsen 目录中查找 css/onsenui.css

  2. MIME类型问题:Go的 http.FileServer 会自动根据文件扩展名设置正确的Content-Type。确保CSS文件扩展名为 .css,JS文件扩展名为 .js

如果问题仍然存在,可以添加调试中间件来查看实际访问的路径:

func debugFileServer(fs http.FileSystem) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Printf("Request path: %s", r.URL.Path)
        http.FileServer(fs).ServeHTTP(w, r)
    })
}

// 使用方式
http.Handle("/static/", 
    http.StripPrefix("/static/", 
        debugFileServer(http.FS(resources.WebUI))))

这会输出每个静态文件请求的实际路径,帮助确认文件系统是否正确映射。

确保HTML模板中引用的静态文件路径正确:

<!-- 在HTML模板中 -->
<link rel="stylesheet" href="/static/css/onsenui.css">
<script src="/static/js/onsenui.js"></script>

文件系统结构应该对应为:

嵌入的WebUI:
public/onsen/css/onsenui.css
public/onsen/js/onsenui.js

访问URL /static/css/onsenui.css 会映射到嵌入文件系统中的 public/onsen/css/onsenui.css

回到顶部