Golang模板中CSS文件MIME类型错误显示为"text/plain"的解决方法

Golang模板中CSS文件MIME类型错误显示为"text/plain"的解决方法 在从Go执行我的index.gohtml模板时,遇到了一个错误,内容为“拒绝应用来自(文件路径)的样式,因为其MIME类型(‘text/plain’)不是受支持的样式表MIME类型,并且启用了严格的MIME检查。”我可以渲染出网站的骨架,但样式无法加载。

即使我在.gohtml文件的href中传入一个不存在的链接,也会得到相同的错误。我已经明确地将链接类型设置为“text/css”。我在想,在执行.gohtml文件之前,是否需要在Go代码中Set()一些东西?我尝试了另一个论坛帖子的解决方案,即.Set(“Content-Type”, “text/css”),但这只是将文件中的实际HTML代码输出到浏览器中。有什么建议吗?

以下是我在Go函数中运行的所有代码:

func index(w http.ResponseWriter, r *http.Request){
    err := tpl.ExecuteTemplate(w, "index.gohtml", nil)
    if err != nil{
        panic(err.Error())
    }
}

更多关于Golang模板中CSS文件MIME类型错误显示为"text/plain"的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

由于我没有看到任何静态文件被提供,那么CSS文件是由什么提供的呢?

更多关于Golang模板中CSS文件MIME类型错误显示为"text/plain"的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你能提供一个能复现该问题的最小化可运行示例吗?

我已经在HTML文件中链接了它。所以我只提供HTML文件,并像通常在前端那样插入一个链接来引入CSS文件。这不是正确的做法吗?

既然你正在使用 gorilla/mux,请在 https://www.gorillatoolkit.org/pkg/mux 上查找 /static/ 的相关内容,这应该能帮你解决问题。

所以,我打开浏览器并指向你的网站,我的浏览器请求页面,你的服务器用HTML响应,然后我的浏览器解析HTML并意识到页面还有资源,于是也请求它们(CSS、JS、图像),这些资源来自响应页面的链接。然后它使用这些资源来构建/渲染页面。

那么,我的问题再次是,如果有的话,是什么返回/提供这些(静态)资源?

类似这样:

package main

import(
	"github.com/gorilla/mux"
	"log"
	"net/http"
	"html/template"
)

var tpl *template.Template

func init(){
	tpl = template.Must(template.ParseGlob("templates/*.gohtml"))
}
 
func main() {
 
  router := mux.NewRouter()
  
  router.HandleFunc("/", index)

  log.Println("Listening on port 8000...")
  log.Fatal(http.ListenAndServe(":8000", router))
}

func index(w http.ResponseWriter, r *http.Request){
	err := tpl.ExecuteTemplate(w, "index.gohtml", nil)
	if err != nil{
		panic(err.Error())
	}
}

我能够正常提供 .gohtml 文件,只是无法链接到 CSS 文件。如果我不通过 Go 来提供服务,而是使用 Node 或 VSCode 扩展启动一个普通的 Web 服务器,那么它就能正常工作。

问题在于Go的http.FileServer默认没有为CSS文件设置正确的MIME类型。当浏览器请求CSS文件时,服务器返回了text/plain而不是text/css。以下是解决方案:

1. 使用自定义文件处理器(推荐)

创建自定义处理器来正确设置CSS文件的MIME类型:

func main() {
    // 静态文件处理
    fs := http.FileServer(http.Dir("static"))
    
    // 包装文件处理器以设置正确的MIME类型
    http.Handle("/static/", http.StripPrefix("/static/", 
        http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // 检查是否为CSS文件
            if strings.HasSuffix(r.URL.Path, ".css") {
                w.Header().Set("Content-Type", "text/css; charset=utf-8")
            }
            fs.ServeHTTP(w, r)
        })))
    
    // 模板路由
    http.HandleFunc("/", index)
    
    http.ListenAndServe(":8080", nil)
}

2. 使用mime包全局注册CSS类型

在程序初始化时注册正确的MIME类型:

import (
    "mime"
    "net/http"
)

func init() {
    // 注册CSS文件的正确MIME类型
    mime.AddExtensionType(".css", "text/css; charset=utf-8")
}

func main() {
    // 静态文件目录
    http.Handle("/static/", http.StripPrefix("/static/", 
        http.FileServer(http.Dir("static"))))
    
    http.HandleFunc("/", index)
    http.ListenAndServe(":8080", nil)
}

3. 完整示例代码结构

项目结构:

project/
├── main.go
├── templates/
│   └── index.gohtml
└── static/
    └── css/
        └── style.css

main.go:

package main

import (
    "html/template"
    "net/http"
    "path/filepath"
)

var tpl *template.Template

func init() {
    // 加载模板
    tpl = template.Must(template.ParseGlob("templates/*.gohtml"))
}

func index(w http.ResponseWriter, r *http.Request) {
    err := tpl.ExecuteTemplate(w, "index.gohtml", nil)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func main() {
    // 静态文件处理(使用自定义处理器)
    fs := http.FileServer(http.Dir("static"))
    
    http.Handle("/static/", http.StripPrefix("/static/", 
        http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // 为CSS文件设置正确的Content-Type
            if filepath.Ext(r.URL.Path) == ".css" {
                w.Header().Set("Content-Type", "text/css; charset=utf-8")
            }
            fs.ServeHTTP(w, r)
        })))
    
    http.HandleFunc("/", index)
    http.ListenAndServe(":8080", nil)
}

index.gohtml模板中的CSS链接:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="/static/css/style.css">
</head>
<body>
    <!-- 页面内容 -->
</body>
</html>

4. 使用http.ServeContent(更精细的控制)

func serveCSS(w http.ResponseWriter, r *http.Request) {
    cssPath := filepath.Join("static", r.URL.Path)
    
    data, err := os.ReadFile(cssPath)
    if err != nil {
        http.Error(w, "Not found", http.StatusNotFound)
        return
    }
    
    w.Header().Set("Content-Type", "text/css; charset=utf-8")
    w.Header().Set("Cache-Control", "public, max-age=86400")
    w.Write(data)
}

func main() {
    http.HandleFunc("/static/css/", serveCSS)
    http.HandleFunc("/", index)
    http.ListenAndServe(":8080", nil)
}

第一种方法是最常用的解决方案,它通过中间件包装文件服务器,在服务CSS文件时动态设置正确的Content-Type头。确保CSS文件路径正确,浏览器就能正确加载样式。

回到顶部