Gzip 線上操作最常見的錯誤,往往來自少數幾個原因:把錯誤的容器貼到目標位置、把 Base64 當成能保護秘密的手段、假設兩個工具一定會產生位元完全相同的輸出,以及貼上一段本來就不是 UTF-8 文字的資料流。Gzip 壓縮與解壓縮工具之所以能讓流程保持簡單,是因為瀏覽器的 Compression Streams API 會建立一個真正的 RFC 1952 gzip 資料流,而頁面會把那份二進位輸出包裝成可以貼上的標準化帶填充 Base64。但「簡單」仍然代表容易誤用,特別是你正把文字在資料庫欄位、HTTP 主體、JSON 設定檔、以及各自期待略有不同容器的 CLI pipe 之間搬移時。本指南整理了會造成靜默失敗的模式、能及早抓出問題的小檢查,以及一套可靠的流程,讓你能在線上壓縮與解壓縮 UTF-8 文字時不遺失資料、不破壞容器完整性,也不浪費一整個下午。

Gzip 線上技巧真正開始重要之處
大多數 gzip 錯誤並不在於演算法——DEFLATE 數十年來一直很穩定——而在於你為包裝層帶進了哪些假設。一段 gzip 資料流是個二進位容器,它以魔術位元組 1f 8b 與一個值為 8 (DEFLATE) 的方法位元組開頭,承載著壓縮區塊,並以一個八位元組的小端序結尾,裡面保存未壓縮資料的 CRC32 與 ISIZE (輸入大小對 2^32 取模)。當你把文字丟進 Gzip 壓縮與解壓縮工具時,這些位元組會在瀏覽器內產生,並立即被重新編碼為帶填充的 Base64,讓結果能順利複製貼上。這個包裝層正是開啟純文字工作流程的關鍵,但它同時也是多數讀者開始踩坑的地方。接收端可能想要原始 gzip、Base64 包裝的 gzip、一個 Content-Encoding 標頭,或是一個 .gz 檔,而這四種期待彼此並不能互換。要乾淨地完成來回轉換,最短的路徑是先決定容器,再去打開轉換器。
會破壞 Gzip 線上來回轉換的錯誤
以下這些模式最常出現在支援討論串、堆疊追蹤,以及事後才發現的損毀記錄中。快速瀏覽一遍,至少能讓未來某個 bug 明顯可避免。
- 又把結果再包一層。如果你的目標位置本身已經有一層 Base64(JSON、multipart 表單、設定檔),不要再在一段已經是 Base64 的 gzip 資料流外面再套一層 Base64。這會把字母表變成兩倍,並打壞所有下游解碼器。
- 為了「整理乾淨」而移除填充符號。頁面輸出的是標準化的帶填充 Base64。移除尾端的等號、插入空白、或以 76 欄寬換行,在某些程式庫仍可解析,在其他程式庫則會壞掉。請保持字串與產生時完全一致。
- 相信不同工具之間位元完全一致。標頭欄位、OS 位元組、mtime、以及 DEFLATE 等級的選擇會因編碼器而異,甚至同一支工具不同次執行也會不同,但解壓縮後的輸出仍然一致。請驗證框架與來回轉換行為,不要去驗證某一個特定的 Base64 字串。
- 要求純文字工具處理 .gz 圖片。如果一個合法的 gzip 資料流展開後是 PNG、ZIP、可執行檔、或舊式編碼的文件,嚴格的解碼器會回報它不是有效的 UTF-8,而不是去竄改位元組。這類情況請改用二進位檔案解壓縮器。
- 計算字元數而非位元組數。Compression Streams 消耗的是 UTF-8 位元組,不是可見字元。一句含有變音符號、表情符號或 CJK 字形的句子,每個字元會佔好幾個位元組,這就是為什麼一小段文字仍可能產出比預期還大的壓縮流。
- 把壓縮當成保密手段。Gzip 沒有金鑰、沒有密碼,也沒有防竄改的完整性保證。任何能讀到那段 Base64 的人都能讀到原始文字,因此千萬不要把憑證或個資塞進一段壓縮資料後就說它受到保護。
- 把內容貼到一個過期的文字欄位。介面會在模式或輸入變更時取消舊的非同步結果,但從舊分頁手動複製貼上的內容仍可能混進來。每次最新狀態列顯示執行完成後,請務必重新複製。
如何在線上壓縮與解壓縮 UTF-8 文字
最快的方式就是這個標準流程:選模式、輸入內容、完整複製結果。在點任何按鈕之前,先確認目標位置期待的容器與你準備產生的一致。
- 把頁面切到「UTF-8 文字轉 gzip Base64」,貼上或輸入你想壓縮的文字。工具會在任何壓縮開始前先把字串讀成 UTF-8,因此變音符號、表情符號和 CJK 字元都會逐位元組保留下來。
- 點擊 Compress,等待狀態確認執行成功。輸出會是一段單一的標準化帶填充 Base64 字串,沒有 data URL 前綴、沒有檔名、也沒有插入的換行。
- 完整複製那段 Base64 字串,包含所有尾端的 = 填充。將它原樣貼進目標欄位;如果你的傳輸方式會加上空白或換行,請在送出前先關閉該行為。
- 若要反過來操作,把模式切到「gzip Base64 轉 UTF-8」,貼上標準化的 Base64 字串,然後點擊 Decompress。頁面會驗證 Base64 字母表、拒絕填充或空白的錯誤、檢查 gzip 魔術位元組與方法位元組,通過之後才把位元組交給串流解壓縮器。
- 將還原後的文字與原文比對。如果頁面回報 UTF-8 錯誤,代表這段 gzip 資料流是有效的,但它的承載內容不是文字;請改送到二進位檔案解壓縮器,不要強行解碼。
瀏覽器會把 CRC32 與 ISIZE 結尾納入一般性的框架檢查,因此損毀或不完整的輸入會大聲失敗,而不會產出半套結果;每端各 5,000,000 位元組的上限則能避免失控的解壓縮把整個分頁凍結。
讀懂 Base64 字串:框架告訴你什麼
一段典型的 Base64 包裝 gzip 資料流,開頭是 H4sI,解碼後對應魔術位元組 1f 8b 08——也就是 gzip 標頭的前三個位元組(ID1、ID2,以及設為 8 代表 DEFLATE 的 CM 壓縮方法欄位)。如果你的目標位置的記錄中出現這個簽章,就代表包裝正確。如果出現 H4sI 但後面接著不同的第一個位元組,代表上游工具用了不同的包裝(zlib、原始 DEFLATE,或非標準標頭),這時該重新指向接收端程式碼,而不是去補貼 Base64。RFC 1952 定義了標頭與結尾中每個固定欄位,所以只要來回轉換看起來有疑問,你隨時可以離線驗證框架。結尾的 CRC32 是用來防止意外損毀的完整性檢查,而不是密碼學簽章,請勿依賴它來偵測竄改。
這裡位元組數量才是重點。文字 "café" 有 4 個可見字元,但編碼後是五個 UTF-8 位元組 0x63 0x61 0x66 0xC3 0xA9——c、a、f,以及 U+00E9 的兩個位元組序列——所以公式基本上是:依據每個字元所屬的 Unicode 碼點範圍計算每字元的位元組數,再加總。Compression Streams 處理的是那五個位元組,而不是你輸入的四個字元,而這種單一字元變兩位元組的躍升,正是來回轉換後最常造成「預期 X 位元組卻得到 Y 位元組」困惑的原因。
速查表:在點擊之前先選對容器
在壓縮任何東西之前,先決定目標位置期待下列四種容器中的哪一種。它們乍看之下很像,骨子裡行為卻大不相同。
| 容器 | 你看到的樣子 | 最適合情境 |
|---|---|---|
| 原始 gzip 位元組 | 一個 .gz 檔,或以 1f 8b 開頭的 HTTP 主體 | 磁碟儲存、CLI pipe、原生二進位 API |
| Base64 包裝的 gzip | 一段由 A–Z、a–z、0–9、+、/ 與尾端 = 組成的長字串 | JSON 值、設定檔的文字欄位、貼上緩衝區 |
| Content-Encoding: gzip | 同一段原始位元組旁邊的一個 HTTP 標頭 | 伺服器對瀏覽器傳輸 HTML、CSS、JS、JSON |
| 含 gzip 的 Data URL | 字串前綴 data:application/gzip;base64, | 把壓縮位元組嵌入 URL 或 Markdown 中 |
不確定的時候,就去問接收端系統。如果它要的是原始位元組,請用像 gzip -c 這類 CLI 工具,或一個能安全處理二進位的檔案端點。如果它要的是 Base64 承載內容,瀏覽器工具就是正確的形狀,而且你可以把結果再丟回接收端的 Gzip 壓縮與解壓縮工具驗證。
什麼情況下 Gzip 線上工具不適合
這個頁面刻意設計為純文字工作流程。它在解壓縮後強制採用嚴格的 UTF-8,並拒絕在位元組無法解碼時用替代字元蒙混過關。下列三種情境應該改用其他工具:承載內容是真正的二進位檔案,例如圖片、壓縮檔或 Windows 可執行檔,這時需要的是二進位檔案 gzip 端點;你需要用於測試 fixture 的確定性輸出,這時用固定旗標的受控 CLI 才能產生穩定的資料流;你需要保密性,這時請用 AES-GCM、age 或 PGP,而不是 gzip。以上這些都不是 gzip 路徑的 bug——它們只是落在純文字合約之外。Base64 解碼常見陷阱 與上面許多錯誤有交集,因為 Base64 就是包裝層,但當失敗模式涉及字母表、填充或 data URL 前綴時,它們值得另外再列一份檢查清單。
跟你的資料一起走得長遠的 Gzip 線上技巧
幾個習慣能讓每一次 gzip 來回轉換都保持可預測。第一,把 Base64 結果當作一整段不中斷的字串複製,別讓你的傳輸工具以 76 欄寬自動換行。第二,改完輸入後,等狀態更新再重新複製,因為介面會取消過時的工作,避免舊的壓縮結果蓋掉新的值。第三,把輸入與還原後的輸出控制在來回兩端各 5,000,000 位元組的上限內;這個上限是為了保護分頁而存在,頁面絕不會悄悄截斷。第四,把 CRC32 視為「我的位元組是否有變動」的偵測器,而非安全性檢查,因為規格在 2.3.1 節正是這樣寫的。第五,把樣本分享給別人時,如果可以的話,Base64 字串與原始 UTF-8 來源都一起給;框架隨時可以重新驗證,但人可讀的意圖只有跟著來源一起才傳得出去。落實這五個習慣,就是把一次成功的一次性轉換,變成明天還能直接重複使用、不必重新除錯每一個步驟的 gzcompress 線上工作流程。
如果你正在權衡選項,URL Decode 速查表:常見代碼與快速修正 有更詳細的說明。