我尝试使用Go在我的HTML模板中包含CSS和JS文件。
这是我的代码main.go
package main
import (
"fmt"
"net/http"
)
func main() {
var mux = http.NewServeMux()
registerRoutes(mux)
httpServer := http.Server{
Addr: ":3000",
Handler: mux,
}
err := httpServer.ListenAndServe()
if err != nil {
fmt.Print(err)
}
}
routes.go
package main
import "net/http"
func registerRoutes(mux *http.ServeMux) {
mux.HandleFunc("/", index)
mux.HandleFunc("/faq", faq)
}
handlers.go
package main
import (
"fmt"
"html/template"
"net/http"
)
func index(w http.ResponseWriter, r *http.Request) {
tmpl, err := template.ParseFiles("templates/index.html")
if err != nil {
fmt.Print(err)
}
err = tmpl.Execute(w, nil)
if err != nil {
fmt.Print(err)
}
}
func faq(w http.ResponseWriter, r *http.Request) {
tmpl, err := template.ParseFiles("templates/faq.html")
if err != nil {
fmt.Print(err)
}
err = tmpl.Execute(w, nil)
if err != nil {
fmt.Print(err)
}
}
index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Index</title>
<link href="../static/stylesheets/main.css" type="text/css" rel="stylesheet">
<script type="text/javascript" src="../static/scripts/index.js"></script>
</head>
<body>
<h1>Test</h1>
</body>
</html>
渲染HTML工作,但它不包括CSS或JS文件。我怎么才能让它认出他们?
谢谢.
**编辑:**根据@Burak塞尔达尔的建议,我实现了以下代码:
已添加到handlers.go
func staticHandler(w http.ResponseWriter, r *http.Request) {
// load the file using r.URL.Path, like /static/scripts/index.js"
path := r.URL.Path
data, err := ioutil.ReadFile(path)
if err != nil {
fmt.Print(err)
}
if strings.HasSuffix(path, "js") {
w.Header().Set("Content-Type","text/javascript")
} else {
w.Header().Set("Content-Type","text/css")
}
_, err = w.Write(data)
if err != nil {
fmt.Print(err)
}
}
添加到routes.go
mux.HandleFunc("/static", staticHandler)
但是,它仍然不起作用。
也许我应该注意到static/
和templates/
在同一个文件夹中,它们与main.go
等共享该文件夹。
**EDIT 2:**看起来我的方法可能不是最好的,所以我尝试使用内置的FileServer
。不过,我不太清楚该怎么做。
我加了这一行
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("C:/Users/x/Documents/Coding/Go/hello_world/"))))
registerRoutes
,但它不工作。
- 我试图在Go中实现类似于Flask的功能。这意味着根据访问的路径重定向到某些模板。我所说的模板是一个可以传递变量的
.html
文件。
- 我试图在Go中实现类似于Flask的功能。这意味着根据访问的路径重定向到某些模板。我所说的模板是一个可以传递变量的
- 我加
fs := http.FileServer(http.Dir("static"))
mux.Handle("/static/", http.StripPrefix("/static", fs))
main.go
中的main()
函数。然后删除了mux.HandleFunc("/static/", staticHandler)
和staticHandler
函数。
**EDIT 5:**假设这是一个很好的方法,我最后关心的是如何处理缓存。很明显,每次页面用tmpl, err := template.ParseFiles("templates/index.html")
等呈现时,我都在解析文件。因此,我想也许我可以添加一个函数来加载这些文件并返回模板,然后在main中调用这个函数并将变量传递给处理程序。这是个好主意吗?你具体会怎么做?这是否意味着我的文件只有在重新启动Web服务器时才能更新?
例如
func initTemplates() (*template.Template, *template.Template) {
indexTemplate := template.Must(template.ParseFiles("templates/index.html"))
faqTemplate := template.Must(template.ParseFiles("templates/faq.html"))
return indexTemplate, faqTemplate
}
func main() {
var mux = http.NewServeMux()
fs := http.FileServer(http.Dir("static"))
mux.Handle("/static/", http.StripPrefix("/static", fs))
indexTemplate, faqTemplate := initTemplates()
...
}
我的问题是,在我的网站上每个页面都有一个这样的变量,这似乎很奇怪。如果我想要100页呢?此外,我如何将这些变量传递给上面定义的处理函数?
EDIT6:
这个怎么样?main.go
var templates map[string]*template.Template
func init() {
if templates == nil {
templates = make(map[string]*template.Template)
}
templates["index.html"] = template.Must(template.ParseFiles("templates/index.html"))
templates["faq.html"] = template.Must(template.ParseFiles("templates/faq.html"))
}
func main() {
var mux = http.NewServeMux()
fs := http.FileServer(http.Dir("static"))
mux.Handle("/static/", http.StripPrefix("/static", fs))
registerRoutes(mux)
httpServer := http.Server{
Addr: ":3000",
Handler: mux,
}
err := httpServer.ListenAndServe()
if err != nil {
fmt.Print(err)
}
}
然后在handlers.go
中使用tmpl := templates["index.html"]
**编辑7:**不确定我是否应该在这一点上提出一个新的问题,但我会继续下去。
我在尝试为资源/purchase/license
提供服务时遇到了一个问题。现在服务器正在该页面上查找/purchase/static/stylesheets/main.css
。我该如何解决此问题?
**EDIT 8:**我通过添加解决了我以前的编辑
mux.Handle("/purchase/static/", http.StripPrefix("/purchase/static", fs))
到main()
。有没有更好、更可扩展的方法来解决这个问题?如果我有数百个/x/y
,我真的需要为每个x
添加一个吗?我可以使用正则表达式或其他东西来添加一个这样的表达式吗?
mux.Handle("*/static/", http.StripPrefix("*/static", fs))
如果是这样,我该怎么做呢?
3条答案
按热度按时间yrefmtwq1#
你还必须“服务”JS和CSS文件。
模板将作为HTML页面呈现和发送。一旦HTML页面被加载,浏览器就会尝试使用页面中的链接加载CSS和JS文件。由于您的服务器不处理这些路由,因此浏览器无法加载它们。
我建议不要使用../static path,而是在HTML中使用/static,并使用加载CSS和JS文件并返回它们的处理程序将该路由挂载到路由器。您还必须设置响应的Content-Type,以便浏览器可以正确使用这些文件。
hwamh0ep2#
感谢@Burak塞尔达尔的指导,我修复了他的一些代码,并添加了一些东西来获得解决方案。
将此添加到
handlers.go
添加到
routes.go
dzhpxtsq3#
对我很有效关键点是静态处理程序的路由器,您需要确保为静态文件引用正确的绝对路径。这是:
dir结构
去跑步:
main.go
首页渲染
静态文件详情
index.html
index.js
index.css