在 Web 上顯示圖片
瞭解如何在網頁上載入和顯示影像。
Web 支援標準的 Image 元件以及更高階的 dart:ui/Image 類(在需要更精細控制來顯示影像時使用)。然而,由於 Web 瀏覽器是為了安全執行不受信任的程式碼而構建的,因此與移動端和桌面端平臺相比,在處理影像時存在一定的侷限性。本頁將解釋這些侷限性,並提供相應的解決方法。
背景
#Web 提供了多種顯示影像的方法
每種選項都有其優缺點。例如,內建元素可以很好地與其他 HTML 元素融合,並且會自動利用瀏覽器快取、內建的影像最佳化和記憶體管理。它們允許你安全地顯示來自任意來源的影像(下文 CORS 部分會詳細介紹)。當影像必須適應使用 <canvas> 元素渲染的其他內容時,drawImage 非常有用。你還可以控制影像大小,並且在 CORS 策略允許的情況下,讀取影像畫素以進行進一步處理。最後,WebGL 為你提供了對影像最高程度的控制。你不僅可以讀取畫素並應用自定義影像演算法,還可以使用 GLSL 進行硬體加速。
跨域資源共享 (CORS)
#
CORS 是一種瀏覽器用於控制一個站點如何訪問另一個站點資源的機制。它的設計初衷是預設不允許一個網站使用 XHR 或 fetch 向另一個站點發起 HTTP 請求。這可以防止其他網站上的指令碼代表使用者行事,並防止在未經許可的情況下訪問另一個站點的資源。
在 Web 上,Flutter 使用 CanvasKit 或 skwasm(使用 Wasm 時)渲染器來渲染應用。這兩者都依賴於 WebGL。WebGL 需要訪問原始影像資料(位元組)才能渲染影像。因此,影像必須來自已配置 CORS 策略並與託管你應用程式的域配合工作的伺服器。
解決方案
#Flutter 中有多種解決 CORS 限制的方法。
記憶體影像、資源影像和同源網路影像
#如果應用已在記憶體中擁有編碼後的影像位元組,或者該影像是作為 資源 (asset) 提供的,亦或是儲存在託管該應用的同一伺服器上(也稱為同源),則無需額外操作。可以使用 Image.memory、Image.asset 或 Image.network 來顯示影像。
在開啟了 CORS 的 CDN 上託管影像
#通常,內容分發網路 (CDN) 可以配置為自定義允許哪些域訪問你的內容。例如,Firebase 站點託管允許在 firebase.json 檔案中指定自定義 Access-Control-Allow-Origin 請求頭。
如果無法控制源伺服器,請使用 CORS 代理
#如果影像伺服器無法配置為允許來自你應用程式的 CORS 請求,你仍然可以透過代理伺服器轉發請求來載入影像。這要求中間伺服器具有足夠的訪問許可權來載入這些影像。
當原始影像伺服器公開提供影像,但未配置正確的 CORS 請求頭時,可以使用此方法。
示例
- 使用 CloudFlare Workers。
- 使用 Firebase Functions。
使用 HTML 平臺檢視
#如果其他解決方案都不適用於你的應用,Flutter 支援使用 HtmlElementView 在應用內嵌入原始 HTML。你可以使用它建立一個 <img> 元素來渲染來自其他域的影像。