部落格

Base64 圖片不顯示?10 個常見原因與修復清單

發佈於 2026 年 4 月 28 日 · 閱讀約 8 分鐘

圖片已經轉成 Base64,data URI 也塞進了 HTML——結果什麼都沒顯示。只看到一個裂圖標。更離譜的是:Chrome 能顯示,Safari 不行;本機能跑,部署就掛。

Base64 圖片顯示失敗之所以令人抓狂,是因為字串看起來完全正常。真正的原因往往藏在細節裡:前綴少了一個字元、複製貼上時混入了不可見的空白、或者後端偷偷做了二次編碼。本文涵蓋全部 10 種常見原因,每種都附帶程式碼範例和修復方法。

速查表:症狀 → 原因 → 修復

先從這裡開始。找到你的症狀,定位可能的原因,再跳到下方看詳細修復。

# 症狀 可能原因 快速修復
1 404 / 裂圖標缺少 data: 前綴補上 data:image/...;base64,
2 空白 / 不渲染; 寫成了 ,修正前綴中的分號
3 空白 / 不渲染base64 後缺逗號補上逗號:base64,
4 圖片殘缺 / 損壞字串被截斷改用 TEXT 欄位類型
5 InvalidCharacterError混入空格 / 非法字元str.replace(/\s/g, '')
6 程式碼裡正常,HTML 裡掛了換行符 \n 污染去掉 \r\n
7 不同瀏覽器行為不一致Padding = 被吃掉URL 編碼或手動補齊
8 通常不會掛MIME 類型不匹配修正即可,非元兇
9 裂圖標,字串長了 ~33%雙重編碼去掉多餘的編碼步驟
10 裂圖標,字串含 \/JSON / URL 跳脫污染JSON.parse()

前綴出錯:data: URI 寫法有誤

data URI 的語法要求非常嚴格。錯一個字元,瀏覽器就會把你的 Base64 字串當作一個壞掉的 URL,而不是圖片資料。

原因 1:整段 data URI 前綴缺失

如果直接把裸的 Base64 字串賦給 src,沒有加 data:image/...;base64, 前綴,瀏覽器會把它當成相對路徑去請求——結果就是 404。

❌ <img src="iVBORw0KGgo..." />
✅ <img src="data:image/png;base64,iVBORw0KGgo..." />

原因 2:分號寫成了逗號

寫成 data:image/png,base64,... 而不是 data:image/png;base64,...,瀏覽器會把 base64,... 當作純文字內容,而不是 Base64 編碼標識。

❌ data:image/png,base64,iVBORw0KGgo...
✅ data:image/png;base64,iVBORw0KGgo...

原因 3:"base64" 後面漏了逗號

base64 和實際資料之間的逗號不能省。如果寫成 data:image/png;base64iVBOR...,瀏覽器會把 base64iVBOR... 當作字元集名稱,而不是編碼資料。

❌ data:image/png;base64iVBORw0KGgo...
✅ data:image/png;base64,iVBORw0KGgo...

編碼損壞:Base64 字串本身有問題

即使前綴完全正確,編碼後的資料也可能在儲存、傳輸或複製貼上過程中被悄悄破壞。

原因 4:字串被截斷

資料庫欄位有長度上限(例如 VARCHAR(65535)),會靜默截斷 Base64 字串。一張 100KB 的 PNG 編碼後約 136,000 個字元——如果欄位在 65,535 處截斷,解碼出來的圖片直接是壞的。修復:儲存 Base64 請使用 TEXTLONGTEXT 類型。

原因 5:混入了非法字元(空格、特殊符號)

合法的 Base64 只包含 A-Za-z0-9+/=。複製貼上時混入的空格會導致 atob() 直接拋出 InvalidCharacterError修復:使用前先去掉所有空白字元:str.replace(/\s/g, '')

原因 6:換行符污染

openssl base64 預設每 76 個字元插入一個 \n(遵循 RFC 2045)。這些換行符在 HTML 的 data URI 裡會導致解碼失敗。修復:使用 openssl base64 -A(單行輸出),或去掉換行:str.replace(/[\r\n]/g, '')

原因 7:Padding 被 URL 解析吃掉

Base64 末尾的 = 填充字元在通過 URL 參數傳遞時經常被吞掉,因為 = 在 URL 中是保留字元。有些瀏覽器能容忍缺失的 padding,有些不行——導致跨環境行為不一致。修復:放入 URL 前先做 encodeURIComponent(),或在接收端手動補齊 padding。

MIME 類型不匹配:真的會掛嗎?

這條可能會讓你意外:宣告了錯誤的 MIME 類型,大多數情況下圖片依然能正常顯示

原因 8:宣告的 MIME 與真實檔案類型不一致

如果你寫了 data:image/png;base64,/9j/4AAQ...(JPEG 資料卻宣告為 PNG),大多數現代瀏覽器依靠內容嗅探(content sniffing)依然能正確渲染。但有兩種場景確實會出問題:(1) 設定了嚴格 CSP 且啟用了 MIME 強制校驗,(2) 伺服端按宣告的 MIME 做格式轉換,導致輸出損壞。結論:修好它是正確做法,但它極少是顯示失敗的真正元兇。

鏈路問題:資料到達瀏覽器前就已經壞了

這類問題最難排查,因為你程式碼裡的 Base64 字串看起來完全正常——損壞發生在序列化或傳輸環節。

原因 9:雙重 Base64 編碼

後端對已經編碼過的資料又做了一次 Base64 編碼,結果變成了對 Base64 字串再做一次 Base64。長度比預期多 ~33%,解碼一次後得到的是文字而不是二進位圖片資料。識別方法:解碼一次,如果結果看起來還是 Base64(字母開頭、= 結尾),說明被雙重編碼了。修復:去掉後端處理鏈路中多餘的編碼步驟。

原因 10:JSON 跳脫或 URL 編碼污染

Base64 字串包含 / 字元。某些 JSON 序列化器會把它跳脫為 \/。如果前端沒有用 JSON.parse 正確解析,而是直接取原始字串,多出來的反斜線就會污染資料。類似地,通過 URL 參數傳遞 Base64 時,+ 會變成空格,= 會被吞掉。修復:JSON 資料務必使用 JSON.parse()。URL 傳輸使用 encodeURIComponent()

系統排查範本

如果以上原因都沒命中,按以下步驟逐項排查:

  1. 在瀏覽器網址列測試 data URI — 把完整的 data:image/...;base64,... 字串直接貼到網址列。如果能顯示,說明問題出在應用注入字串的方式上。
  2. 檢查瀏覽器主控台 — 按 F12,在 Console 標籤頁查找 net::ERR_INVALID_URL 或 CSP 違規等錯誤訊息。
  3. 比對字串長度 — 對比源頭(後端)和前端拿到的 Base64 字串長度。如果不一致,說明傳輸過程中發生了截斷或損壞。
  4. 解碼並檢查 — 在主控台用 atob() 解碼前幾個字元。如果拋出 InvalidCharacterError,說明字串中混入了非法字元。
  5. 檢測雙重編碼 — 解碼一次。如果結果看起來還像 Base64 字串,再解碼一次。如果第二次解碼得到了二進位資料,說明處理鏈路中存在多餘的編碼步驟。

用 ViewJSON 一鍵驗證 Base64

與其手動檢查 Base64 字串,不如直接把 JSON 貼到 ViewJSON。它透過魔數偵測自動識別 Base64 編碼的媒體並渲染行內預覽——如果預覽正常出現,說明你的 Base64 是有效的;如果沒有,你可以精確定位是哪個欄位出了問題。

相關文章

優雅地偵錯 JSON API 回應中的 Base64 圖片 →

立即體驗

貼上你的 Base64 字串,立刻驗證是否能正確渲染——完全在瀏覽器中完成,無需上傳。

開啟 ViewJSON →