1

I have already set the value of contest-encoding, but how can I gzip the template, since the file is still to big.

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
    }   
}

Is there any function that can gzip the response?]

Followed by the advise, I changed my code as this:

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
    }   
}

But when I query the url, I only download the gzip file. What's wrong with it?

Wyatt
  • 141
  • 1
  • 2
  • 9
  • 1
    Also never parse your templates inside the handler, especially if it's large. For details see [It takes too much time when using “template” package to generate a dynamic web page to client in golang](http://stackoverflow.com/a/28453523/1705598) – icza Oct 04 '16 at 07:37
  • @icza It's not about the global variable. Because the .js and .css file is too big, it takes too much time for the browser to download the web content. – Wyatt Oct 09 '16 at 13:42

4 Answers4

2

You can use package 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.

In your code, it might look like this:

gz := gzip.NewWriter(w)
defer gz.Close()

err = tmpl.Execute(gz, nil)
if err != nil {
    http.Error(gz, err.Error(), http.StatusInternalServerError)
    return
}

Ps.

You might want to check the Accept-Encoding header in the request to see if the browser accepts gzip encoded content.

ANisus
  • 74,460
  • 29
  • 162
  • 158
  • I have tried this code, but when I query this url. I only donwload this zip file. My code is given above – Wyatt Oct 09 '16 at 13:33
1
r.Header.Set("Accept-Encoding", "gzip")

Setting the headers on the request has no effect. You would want to read this header to determine whether to use gzip.

The reason the browser downloads the file instead of rendering it is that it's missing a content type. When you write to an http.ResponseWriter without setting the Content-Type there's an algorithm that determines the Content-Type and sets the correct header. But with your body gzipped, it can't determine the correct content type. Add this before you write any data back to the client:

w.Header().Set("Content-Type", "text/html")
areed
  • 11
  • 1
0

This is a bit to late but i hope someone else finds this usefull.

The code works but you need to set the header to be properly interpreted by the browser:

w.Header().Add("Content-Type","text/html")
w.Header().Add("Content-Encoding","gzip")
-1

Anyway, I have not solved this problem. As I mentioned, when I add this code, restart the server and query this url, I actually download the zip file!?

In the end, I used Nginx to make a reverse proxy to compress the template. It works.

Still thanks to @Anisus

Wyatt
  • 141
  • 1
  • 2
  • 9