LINE Imagemap 陷阱:baseUrl 原來不是一張圖!
在最近的某個專案當中,客戶希望在 LINE 官方帳號的互動中,使用 Imagemap 訊息格式。
Imagemap 可以讓使用者點擊圖片上的不同區塊,以便於觸發不同的行為,例如導向不同的網頁、回傳不同的文字訊息,非常適合設計互動式選單或導覽。
例如,假設你用底下這張圖當作Imagemap:
則可以設定成,如果用戶點選左邊,則會出現 鶯歌 的簡介,點右邊,則會出現八德的簡介。
我的 team member 馬上動手實作,照著文件寫下程式碼,其中一則 Imagemap 訊息的json代碼類似底下這樣:
{
"type": "imagemap",
"baseUrl": "https://example.com/images/sample.png",
"altText": "選單",
"baseSize": { "width": 1040, "height": 1040 },
"actions": [
{
"type": "uri",
"linkUri": "https://example.com/page1",
"area": { "x": 0, "y": 0, "width": 520, "height": 520 }
}
]
}
但是,不管怎麼設定,圖片就是顯示不出來。總是出現類似底下這樣的錯誤訊息:
debug 了好一陣子,毫無頭緒。
同仁跑來問我時,我看了一眼,突然想起以前也踩過這個坑。
其實, baseUrl 並不是一張圖片的 URL!
此參數之所以叫做「baseUrl」,是因為它代表的是 圖片的基底路徑。(而非圖片的路徑)
LINE Imagemap 為了要在不同裝置(例如手機解析度不同)都能有合適的圖片顯示,會自動從這個 baseUrl 延伸出不同尺寸所需要的圖片 URL。
LINE 需要哪些圖片尺寸?
LINE 規定 Imagemap 至少要提供以下幾種尺寸的圖片:
- 1040 px:完整解析度,給大多數手機使用
- 700 px:中等解析度
- 460 px:小尺寸裝置
LINE 如何組合圖片 URL?
假設程式裡設定:
"baseUrl": "https://example.com/images/sample"
當 LINE 需要 1040 尺寸圖片時,它實際會去抓:
https://example.com/images/sample/1040
這樣的網址(請注意這網址必須指向一張圖片)。
同樣的邏輯:
-
700 圖片 →
https://example.com/images/sample/700
-
460 圖片 →
https://example.com/images/sample/460
這也解釋了為什麼要 特別提醒不能在 baseUrl 裡加副檔名,因為 LINE 會自己在後面拼上尺寸數字,而其中並沒有副檔名。
正確的做法
因此,若是採用一般的網站儲存 ImageMap 所需的圖片時, baseUrl 指向的就不是單一一張圖片,而是指向一個「資料夾」。
在該資料夾底下,你必須放置不同尺寸的數張圖片,且檔名必須是數字(無附檔名):
/images/sample/1040 → 1040x1040 的圖
/images/sample/700 → 700x700 的圖
/images/sample/460 → 460x460 的圖
只要這樣配置好,LINE 就能根據裝置需求去抓對應尺寸的圖檔,Imagemap 才能正確顯示。
小結
Imagemap 的 baseUrl
是很多人第一次踩雷的地方。
一開始會以為它就是「圖片 URL」,但實際上,它更像是「圖片路徑前綴」或「資料夾位置」。
只要理解這個原理,並準備好不同尺寸的圖片,放入baseUrl指向的資料夾中,就能順利完成 LINE Imagemap 的設定。
後記
有人問到…
為什麼圖片檔案沒有附檔名?
這也是很多人第一次使用 Imagemap 時的疑問:為什麼圖片 URL 後面沒有 .jpg
或 .png
副檔名?
我想原因是因為, LINE 為了在處理 Imagemap
在不同的手機上都能有最完美的全版顯示,自動在路徑後面加上尺寸數字(如 /1040
、/700
、/460
)以便於取得最適圖片。為了能直接向伺服器請求這個 URL,且同時又要能接受JPEG 或 PNG格式,因此乾脆要求圖片不要有附檔名。
再者網路上圖片的實際格式(JPEG 或 PNG),不是靠副檔名判斷,而是靠伺服器回傳的 HTTP Header 中的 Content-Type
。
舉例來說:
- 當 LINE 請求
https://example.com/images/sample/1040
- 伺服器必須回應:
HTTP/1.1 200 OK
Content-Type: image/png
(或)
HTTP/1.1 200 OK
Content-Type: image/jpeg
也就是說,副檔名其實不是必要資訊,伺服器採用Content-Type告訴 LINE 這是一張 PNG 或 JPEG 就夠了。
後記的後記
在實務上,有些開發者發現一個「取巧」的做法:
假設你只有一張圖片(例如 sample.png
),不想另外準備 1040
、700
、460
三份不同尺寸的圖片檔案,於是就把 baseUrl
設成:
https://example.com/images/sample.png?
這樣 LINE 拼接圖片URL時會依照手機尺寸去抓:
- https://example.com/images/sample.png?/1040
- https://example.com/images/sample.png?/700
- https://example.com/images/sample.png?/460
在某些伺服器(包含 Azure Blob Storage),這樣的 URL 仍然會回傳原本的 sample.png
,因為後端會把 ?/1040
當成「查詢字串」的一部分而忽略了它。
結果就是,不管 LINE 要求哪個尺寸,實際上都只回同一張圖。
這個方法看似方便,能快速解決「沒有多尺寸圖片」的問題,但風險是:
- 不符合官方規範:LINE 文件明確要求
baseUrl
不能包含副檔名。 - 跨環境不保證可用:不同的 CDN、Proxy、或安全設備可能會把
?/1040
視為錯誤路徑,導致圖片抓不到。 - 未來相容性風險:若 LINE 改變 URL 拼接方式(例如改用 query 參數),這個技巧可能立即失效。
因此,這個方法只能算是一種「workaround」,用於臨時測試或實驗場合可以,但若是正式專案,仍建議依照規格設計三個尺寸的圖片或透過 CDN/Front Door 作 URL Rewrite Mapping。
留言