nos*_*bee 5 html http go go-templates
当我尝试将值传递给.html
代码时,我正在使用该html/template
包.
但是,我似乎无法设置.css
我的.html
文件中引用的内容类型.它以纯文本形式提供给浏览器,因此忽略了格式化.
在一个静态.html
文件中,我可以使用内置函数http.Fileserver
来处理内容类型,但然后模板化不起作用.我无法传递变量.它只显示为{{.}}
有没有办法将content-type
内置文件服务器的便利性http.Fileserver
与模板能力结合起来http.HandleFunc
?
这是我的代码,因为它没有使用http.Fileserver
.注意,我的Go
文件位于起始目录中,index.html
而且.css
文件位于子目录中/hello/
:
package main
import (
"html/template"
"io/ioutil"
"log"
"net/http"
)
var Message string = "test page"
func servePipe(w http.ResponseWriter, req *http.Request) {
dat, err := ioutil.ReadFile("hello/index.html")
if err != nil {
log.Fatal("couldn't read file:", err)
}
templ, err := template.New("Test").Parse(string(dat))
if err != nil {
log.Fatal("couldn't parse page:", err)
}
templ.Execute(w, Message)
}
func main() {
http.HandleFunc("/hello/", servePipe)
http.ListenAndServe(":8080", nil)
}
Run Code Online (Sandbox Code Playgroud)
这是我的.html
档案.正在提供html页面没有任何问题.它.css
是未提供的单独文件(在.html
文件中链接),因此不会发生格式化.
<!DOCTYPE html>
<html>
<head>
<title>Test Page</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<p>{{.}}</p>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
Template.Execute()
将通过调用Write()
传递的方法来“传递”内容io.Writer
,在您的情况下是http.ResponseWriter
.
如果您在第一次调用之前没有设置内容类型ResponseWriter.Write()
(在您的示例中没有设置),那么net/http
包将尝试检测内容类型(基于写入的前 512 个字节),并将自动设置它为您(以及WriteHeader(http.StatusOK)
ifResponseWriter.WriteHeader()
尚未被调用)。
这是记录在http.ResponseWriter.Write()
:
// Write writes the data to the connection as part of an HTTP reply.
//
// If WriteHeader has not yet been called, Write calls
// WriteHeader(http.StatusOK) before writing the data. If the Header
// does not contain a Content-Type line, Write adds a Content-Type set
// to the result of passing the initial 512 bytes of written data to
// DetectContentType.
//
// ...
Write([]byte) (int, error)
Run Code Online (Sandbox Code Playgroud)
所以如果你index.html
看起来像这样:
<html>
<body>
This is the body!
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
然后这将被正确地检测为 HTML 文档,因此text/html
将自动设置内容类型。如果您没有出现这种情况,则意味着您index.html
的文件未被识别为 HTML 文档。所以只要确保你的模板文件是有效的 HTML / CSS / 等。文档和内容类型将被自动和正确地推断出来。
另请注意,如果它在某些“极端”情况下不起作用,您始终可以通过在调用之前手动设置它来“覆盖”它,Template.Execute()
如下所示:
w.Header().Set("Content-Type", "text/html")
templ.Execute(w, Message)
Run Code Online (Sandbox Code Playgroud)
旁注:不要在处理程序中读取和解析模板,有关详细信息,请参阅相关问题:在 golang 中使用“模板”包为客户端生成动态网页需要花费太多时间
如果您提供的模板引用了其他模板,它们将不会被神奇地加载和执行。在这种情况下,您应该有一个包含所有模板的“预加载”模板。template.ParseFiles()
并且template.ParseGlob()
是一次加载多个模板文件的好“工具”。
所以,如果你的index.html
引用style.css
,那么你必须要对服务照顾style.css
过。如果它不是模板(但例如静态文件),您可以使用此处提供的多个选项提供它:在 Go 模板中包含 js 文件
如果它也是一个模板,那么您还必须加载它并通过调用Template.ExecuteTemplate()
.
一个示例解决方案是使用template.ParseFiles()
,并使用路径来“指定”您想要提供的模板(从客户端/浏览器端)。
例如,请求路径/hello/index.html
可以为"index.html"
模板提供服务,请求路径/hello/style.css
(这将在接收和处理 之后由浏览器自动完成index.html
)可以为"style.css"
模板提供服务。它可能看起来像这样(为简洁起见省略了错误检查):
parts := strings.Split(req.URL.Path, "/") // Parts of the path
templName := parts[len(parts)-1] // The last part
templ.ExecuteTemplate(w, templName, someDataForTemplate)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1943 次 |
最近记录: |