Golang中URL尾部斜杠导致CSS/JS无法加载的问题
Golang中URL尾部斜杠导致CSS/JS无法加载的问题 我遇到了一个问题:当URL路径末尾添加斜杠时,静态资源无法加载。
https://static.go4webdev.org/why (工作正常)
SVG文件的路径将是 /icn/meatballs.svg
https://static.go4webdev.org/why/ (无法加载CSS/JS等)
SVG文件的路径将是 why/icn/meatballs.svg
这在一定程度上破坏了指向公共文件夹中某些资源的路径。
func init() {
tpl = template.Must(template.ParseGlob("public/tmpl/*.html"))
http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir("./public/img"))))
http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("./public/css"))))
http.Handle("/icn/", http.StripPrefix("/icn/", http.FileServer(http.Dir("./public/icn"))))
http.Handle("/js/", http.StripPrefix("/js/", http.FileServer(http.Dir("./public/js"))))
http.Handle("/mov/", http.StripPrefix("/mov/", http.FileServer(http.Dir("./public/mov"))))
http.Handle("/misc/", http.StripPrefix("/misc/", http.FileServer(http.Dir("./public/misc"))))
}
有什么办法可以正确加载页面吗?
更多关于Golang中URL尾部斜杠导致CSS/JS无法加载的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
HTML中相对路径的工作原理是这样的(这是浏览器的问题,不是Go语言的问题)。存在以下几种可能的解决方案(顺序是随机的,只是我想到的顺序,不代表任何偏好):
- 对资源使用绝对路径而非相对路径
- 始终将带尾部斜杠的路径重定向到不带尾部斜杠的路径,并相应地编写资源引用
- 始终将不带尾部斜杠的路径重定向到带尾部斜杠的路径,并相应地编写资源引用
- 设置一个
<base>标签,并相应地编写资源引用
更多关于Golang中URL尾部斜杠导致CSS/JS无法加载的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这个问题是由于相对路径解析导致的。当URL以斜杠结尾时,浏览器会将相对路径解析为相对于当前目录,而不是相对于根目录。
解决方案是使用绝对路径或添加<base>标签。以下是两种实现方式:
方案一:在HTML模板中使用绝对路径
// 在模板中使用绝对路径
<link rel="stylesheet" href="/css/style.css">
<script src="/js/app.js"></script>
<img src="/img/logo.png">
方案二:在模板中添加base标签
// 在HTML模板的<head>中添加
<base href="/">
// 或者在Go代码中动态设置
func renderTemplate(w http.ResponseWriter, tmpl string, data interface{}) {
// 设置base URL
w.Header().Set("Content-Type", "text/html; charset=utf-8")
// 解析并执行模板
err := tpl.ExecuteTemplate(w, tmpl+".html", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
方案三:使用URL重写(更彻底的解决方案)
func init() {
// 静态文件服务配置保持不变
http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir("./public/img"))))
http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("./public/css"))))
http.Handle("/icn/", http.StripPrefix("/icn/", http.FileServer(http.Dir("./public/icn"))))
http.Handle("/js/", http.StripPrefix("/js/", http.FileServer(http.Dir("./public/js"))))
// 主处理器,移除尾部斜杠
http.HandleFunc("/why", func(w http.ResponseWriter, r *http.Request) {
// 如果请求以斜杠结尾,重定向到没有斜杠的版本
if r.URL.Path == "/why/" {
http.Redirect(w, r, "/why", http.StatusMovedPermanently)
return
}
// 正常处理请求
err := tpl.ExecuteTemplate(w, "why.html", nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
}
方案四:使用中间件统一处理尾部斜杠
func RemoveTrailingSlash(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 保留根路径的斜杠,移除其他路径的尾部斜杠
if r.URL.Path != "/" && strings.HasSuffix(r.URL.Path, "/") {
http.Redirect(w, r, strings.TrimSuffix(r.URL.Path, "/"), http.StatusMovedPermanently)
return
}
next.ServeHTTP(w, r)
})
}
// 使用中间件
func main() {
// 配置静态文件服务...
// 包装处理器
handler := RemoveTrailingSlash(http.DefaultServeMux)
http.ListenAndServe(":8080", handler)
}
推荐使用方案一或方案三。方案一最简单直接,方案三可以统一URL格式,避免重复内容问题。

