Golang服务主页并提供模板化页面

时间:2014-06-08 23:28:56

标签: url static go

我希望在url =“/”处设置一个静态目标网页,然后使用模板提供任何文件url =“/”+文件。

我的模板正常运行

package main

import (
"html/template"
"log"
"net/http"
"os"
"path"
)

func main() {
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))

http.HandleFunc("/", serveTemplate)

log.Println("Listening...")
http.ListenAndServe(":5000", nil)
}

func serveTemplate(w http.ResponseWriter, r *http.Request) {
lp := path.Join("templates", "layout.html")
fp := path.Join("templates", r.URL.Path)

// Return a 404 if the template doesn't exist
info, err := os.Stat(fp)
if err != nil {
    if os.IsNotExist(err) {
        http.NotFound(w, r)
        return
    }
}

// Return a 404 if the request is for a directory
if info.IsDir() {
    http.NotFound(w, r)
    return
}

templates, err := template.ParseFiles(lp, fp)
if err != nil {
    log.Print(err)
    http.Error(w, "500 Internal Server Error", 500)
    return
}
templates.ExecuteTemplate(w, "layout", nil)
}

所以这很好用。基本上,我认为我需要做两件事。一,在我的main()函数中添加另一个http.Handle或http.HandlerFunc来处理单个html文件,然后让我的错误检查器重定向而不是抛出404错误。

请帮助我如何做到这一点或提供更好的解决方案?

1 个答案:

答案 0 :(得分:2)

我建议阅读:http://golang.org/doc/articles/wiki/#tmp_6 - 它涵盖了很多内容。

具体做法是:

  • 您正在阻止每个读取文件系统的请求(坏!);
  • 然后你会在每个请求中解析你的模板文件(慢);
  • 使用URL路径的一部分直接从文件系统读取是一个巨大的安全问题(即使Go试图逃避它,期望有人击败它)。对此非常小心

您还应该在程序启动期间(即在main()开始时)解析模板一次。使用tmpl := template.Must(template.ParseGlob("/dir"))从目录中提前阅读所有模板 - 这将允许您从路线中查找模板。 html/template文档涵盖了这一点。

请注意,您需要编写一些逻辑来捕获您尝试从路径中匹配的模板在处理程序中不存在。

如果您想要更多功能,我还会考虑使用gorilla/mux。您可以编写一个未找到的处理程序,使用302(临时重定向)重定向到/,而不是引发404。

r := mux.NewRouter()

r.HandleFunc("/:name", nameHandler)
r.HandleFunc("/", rootHandler)
r.NotFoundHandler(redirectToRoot)
http.Handle("/", r)

log.Fatal(http.ListenAndServe(":8000", nil))

func redirectToRoot(w http.ResponseWriter, r *http.Request) {
    http.Redirect(w, r, "/", http.StatusSeeOther)
}

希望有所帮助。