如何在golang web中gzip一个模板
how to gzip a template in golang web
我已经设置了contest-encoding的值,但是我怎么gzip这个模板,因为文件还是很大。
func indexPageHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Encoding", "gzip")
r.Header.Set("Accept-Encoding", "gzip")
tmpl, err := template.New("index.html").ParseGlob("./templates/*")
if err != nil {
log.Println(err)
return
}
err = tmpl.Execute(w, nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
有没有gzip响应的函数?]
按照建议,我将代码更改为:
func indexPageHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Encoding", "gzip")
r.Header.Set("Accept-Encoding", "gzip")
gz := gzip.NewWriter(w)
defer gz.Close()
tmpl, err := template.New("index.html").ParseGlob("./templates/*")
if err != nil {
log.Println(err)
return
}
err = tmpl.Execute(gz, nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
但是当我查询 url 时,我只下载了 gzip 文件。怎么了?
您可以使用包 compress/gzip
:
func NewWriter(w io.Writer) *Writer
NewWriter returns a new Writer.
Writes to the returned writer are compressed and written to w.
It is the caller's responsibility to call Close on the WriteCloser
when done. Writes may be buffered and not flushed until Close.
在您的代码中,它可能如下所示:
gz := gzip.NewWriter(w)
defer gz.Close()
err = tmpl.Execute(gz, nil)
if err != nil {
http.Error(gz, err.Error(), http.StatusInternalServerError)
return
}
Ps.
您可能需要检查请求中的 Accept-Encoding
header 以查看浏览器是否接受 gzip 编码的内容。
反正我没有解决这个问题。正如我提到的,当我添加这段代码,重新启动服务器并查询这个 url,我实际上下载了 zip 文件!?
最后还是用Nginx做了一个反向代理来压缩模板。有效。
还是感谢@Anisus
r.Header.Set("Accept-Encoding", "gzip")
对请求设置 headers 无效。您可能需要阅读此 header 以确定是否使用 gzip。
浏览器下载文件而不是呈现文件的原因是它缺少内容类型。当您写入 http.ResponseWriter 而不设置 Content-Type 时,有一种算法可以确定 Content-Type 并设置正确的 header。但是随着你的 body gzipped,它无法确定正确的内容类型。在将任何数据写回客户端之前添加:
w.Header().Set("Content-Type", "text/html")
这有点晚了,但我希望其他人觉得这很有用。
代码有效,但您需要设置 header 以便浏览器正确解释:
w.Header().Add("Content-Type","text/html")
w.Header().Add("Content-Encoding","gzip")
我已经设置了contest-encoding的值,但是我怎么gzip这个模板,因为文件还是很大。
func indexPageHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Encoding", "gzip")
r.Header.Set("Accept-Encoding", "gzip")
tmpl, err := template.New("index.html").ParseGlob("./templates/*")
if err != nil {
log.Println(err)
return
}
err = tmpl.Execute(w, nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
有没有gzip响应的函数?]
按照建议,我将代码更改为:
func indexPageHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Encoding", "gzip")
r.Header.Set("Accept-Encoding", "gzip")
gz := gzip.NewWriter(w)
defer gz.Close()
tmpl, err := template.New("index.html").ParseGlob("./templates/*")
if err != nil {
log.Println(err)
return
}
err = tmpl.Execute(gz, nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
但是当我查询 url 时,我只下载了 gzip 文件。怎么了?
您可以使用包 compress/gzip
:
func NewWriter(w io.Writer) *Writer
NewWriter returns a new Writer.
Writes to the returned writer are compressed and written to w.It is the caller's responsibility to call Close on the WriteCloser
when done. Writes may be buffered and not flushed until Close.
在您的代码中,它可能如下所示:
gz := gzip.NewWriter(w)
defer gz.Close()
err = tmpl.Execute(gz, nil)
if err != nil {
http.Error(gz, err.Error(), http.StatusInternalServerError)
return
}
Ps.
您可能需要检查请求中的 Accept-Encoding
header 以查看浏览器是否接受 gzip 编码的内容。
反正我没有解决这个问题。正如我提到的,当我添加这段代码,重新启动服务器并查询这个 url,我实际上下载了 zip 文件!?
最后还是用Nginx做了一个反向代理来压缩模板。有效。
还是感谢@Anisus
r.Header.Set("Accept-Encoding", "gzip")
对请求设置 headers 无效。您可能需要阅读此 header 以确定是否使用 gzip。
浏览器下载文件而不是呈现文件的原因是它缺少内容类型。当您写入 http.ResponseWriter 而不设置 Content-Type 时,有一种算法可以确定 Content-Type 并设置正确的 header。但是随着你的 body gzipped,它无法确定正确的内容类型。在将任何数据写回客户端之前添加:
w.Header().Set("Content-Type", "text/html")
这有点晚了,但我希望其他人觉得这很有用。
代码有效,但您需要设置 header 以便浏览器正确解释:
w.Header().Add("Content-Type","text/html")
w.Header().Add("Content-Encoding","gzip")