Golang中CSS文件被作为text/html类型返回的问题
Golang中CSS文件被作为text/html类型返回的问题
package main
import (
"fmt"
"html/template"
"log"
"net/http"
)
//allTemplates is of type pointer to a template
var allTemplates *template.Template
func contact(writer http.ResponseWriter, request *http.Request) {
err := request.ParseForm()
check(err)
err = allTemplates.ExecuteTemplate(writer, "index.html", request.Form)
check(err)
}
func init() {
allTemplates = template.Must(template.ParseFiles("public/html/index.html"))
}
func main() {
http.HandleFunc("/", contact)
http.Handle("/css", http.FileServer(http.Dir("public")))
http.Handle("/js/", http.FileServer(http.Dir("public")))
http.Handle("/images/", http.FileServer(http.Dir("public")))
http.Handle("/media-files/", http.FileServer(http.Dir("public")))
log.Fatal(http.ListenAndServe(":8080", nil))
}
func check(err error) {
if err != nil {
fmt.Println(err)
}
}
如果您能抽空审阅这段代码,我将不胜感激
更多关于Golang中CSS文件被作为text/html类型返回的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我将
http.Handle("/css", http.FileServer(http.Dir("public")))
改为
http.Handle("/css", http.FileServer(http.Dir("./public")))
之后一切工作正常,但我想了解这种行为的原因,因为其他文件(如图片)在目录名前都没有添加"./"前缀,但一切都能正常工作。
另外,文件服务器会使用相应的Content-Type头部来提供文件,我在示例中使用了相同的方式,但对于不同的文件类型,其行为表现却有所不同。
更多关于Golang中CSS文件被作为text/html类型返回的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我不太确定回退到内容嗅探的具体工作原理,但第一阶段使用的 mime.TypeByExtension 在 Windows 上需要注册表支持,并且(或曾经)容易受到交叉编译损坏或目标计算机上缺少注册表项的影响。也就是说,至少在 Windows 系统上,这种自动检测功能的可靠性比我预期的要低。
不过我认为正如 lutzhorn 所说,这会导致返回 application/octet-stream。你确定得到的结果不是这样的吗?可能是浏览器在此基础上添加了它自己的默认设置。
如果我正确理解了您的问题,您是在询问为什么
http.Handle("/css", http.FileServer(http.Dir("public")))
返回的CSS文件带有Content-Type头部为text/html。
我无法复现这个问题。下面这个简单的程序
package main
import (
"log"
"net/http"
)
func main() {
// 简单的静态网页服务器:
log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("/tmp/styles"))))
}
能够正确地从/tmp/styles目录提供CSS文件,并返回Content-Type: text/css:
$ curl -i http://localhost:8080/foo.css
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 35
Content-Type: text/css; charset=utf-8
Last-Modified: Sun, 13 May 2018 14:52:05 GMT
Date: Sun, 13 May 2018 14:54:09 GMT
* {
font-family: sans-serif;
}
我仍然无法复现这个问题。即使我将代码改为:
log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("./styles"))))
并在包含styles/的目录中运行此程序,foo.css的Content-Type仍然设置为text/css。
让我们看一下源代码:
// If the response's Content-Type header is not set, ServeContent
// first tries to deduce the type from name's file extension and,
// if that fails, falls back to reading the first block of the content
// and passing it to DetectContentType.
让我们看一下net/http.DetectContentType:
DetectContentType 实现了 http://mimesniff.spec.whatwg.org/ 中描述的算法来确定给定数据的 Content-Type。它最多考虑数据的前512个字节。DetectContentType 总是返回一个有效的 MIME 类型:如果无法确定更具体的类型,它将返回 “application/octet-stream”。
- 你的 CSS 文件叫什么名字?它们是否有
.css扩展名? - 如果没有,它们的前512个字节包含什么内容?这些内容是否足以判断它们包含的是 CSS 而不是其他语言(如 C 或 JavaScript)?
问题在于你的静态文件路由配置不正确,导致CSS文件被错误地作为text/html类型返回。主要问题是路由路径和实际文件路径不匹配。
以下是修正后的代码:
package main
import (
"fmt"
"html/template"
"log"
"net/http"
"path/filepath"
)
var allTemplates *template.Template
func contact(writer http.ResponseWriter, request *http.Request) {
err := request.ParseForm()
check(err)
err = allTemplates.ExecuteTemplate(writer, "index.html", request.Form)
check(err)
}
func init() {
allTemplates = template.Must(template.ParseFiles("public/html/index.html"))
}
func main() {
// 修正静态文件服务配置
http.HandleFunc("/", contact)
// 使用StripPrefix来正确处理文件路径
http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("public/css"))))
http.Handle("/js/", http.StripPrefix("/js/", http.FileServer(http.Dir("public/js"))))
http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir("public/images"))))
http.Handle("/media-files/", http.StripPrefix("/media-files/", http.FileServer(http.Dir("public/media-files"))))
log.Fatal(http.ListenAndServe(":8080", nil))
}
func check(err error) {
if err != nil {
fmt.Println(err)
}
}
关键修改点:
-
修正路由路径:所有静态文件路由都添加了尾部斜杠
/css/而不是/css -
使用StripPrefix:正确剥离URL前缀,将请求路径映射到正确的文件系统路径
-
指定具体目录:每个静态文件服务指向特定的子目录
如果你的目录结构是这样的:
public/
├── css/
│ └── style.css
├── js/
│ └── script.js
├── images/
│ └── logo.png
├── media-files/
│ └── video.mp4
└── html/
└── index.html
现在CSS文件将通过正确的MIME类型返回:
/css/style.css→text/css/js/script.js→application/javascript/images/logo.png→image/png
这样配置后,浏览器将正确识别和处理CSS文件,避免被当作HTML内容解析。

