2025-03-31

練習:建立一個使用 GZ 壓縮的頁面

程式碼

以 go 語言來寫:

package main

import (
	"compress/gzip"
	"net/http"
)

// 測試頁的 HTML 內容
const content = `<!DOCTYPE html>
<html lang="en">
	<head>
		<title>Test</title>
		<meta charset="utf-8" />
	</head>
	<body>
		<h1>Lorem ipsum dolor</h1>
		<p>Donec pretium dictum est quis hendrerit. Mauris accumsan, dolor eu vehicula commodo, nunc velit laoreet leo, commodo pellentesque sem est in libero. </p>
	</body>
</html>`

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Encoding", "gzip")
		w.Header().Set("Content-Type", "text/html")
		w.Header().Set("Aceppt-Encoding", "gzip")

		gzipWriter := gzip.NewWriter(w)

		defer gzipWriter.Close()
		gzipWriter.Write([]byte(content))

	})

	http.ListenAndServe(":8080", nil)
}

執行後,在瀏覽器打開 http://localhost:8080 ,會出現正常的網頁,原始碼同 content 變數的內容

可是用 curl 卻是:

C:\> curl localhost:8080 -i
HTTP/1.1 200 OK
Aceppt-Encoding: gzip
Content-Encoding: gzip
Content-Type: text/html
Date: Mon, 31 Mar 2025 05:24:57 GMT
Content-Length: 10

Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.

06/13 補充

curl 那是因為我實際上的 Response Body 真的是個 gzip 檔案

要避免發出 Request 是像是 curl 這樣沒支援顯示 gzip 壓縮的程式,就得判定對方是否支援 gzip 壓縮

參照 MDN 上 Accept-Encoding header 的說明,Accept-Encoding Header 要註記 gzip 才表示支援 gzip 壓縮

所以 main func 要改成


func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if strings.ContainsAny(r.Header.Get("Accept-Encoding"), "gzip") {
			// 支援 gzip 壓縮時,以 gzip 壓縮內容
			w.Header().Set("Content-Encoding", "gzip")
			w.Header().Set("Content-Type", "text/html")
			w.Header().Set("Aceppt-Encoding", "gzip")

			gzipWriter := gzip.NewWriter(w)

			defer gzipWriter.Close()
			gzipWriter.Write([]byte(content))
		} else {
			w.Write([]byte(content))
		}

	})

	http.ListenAndServe(":8080", nil)
}

沒有留言:

張貼留言