跳到主内容

在 Web 上显示图片

了解如何在网页上加载和显示图像。

Web 支持标准的 Image 组件以及更高级的 dart:ui/Image 类(在需要更精细控制来显示图像时使用)。然而,由于 Web 浏览器是为了安全运行不受信任的代码而构建的,因此与移动端和桌面端平台相比,在处理图像时存在一定的局限性。本页将解释这些局限性,并提供相应的解决方法。

背景

#

Web 提供了多种显示图像的方法

每种选项都有其优缺点。例如,内置元素可以很好地与其他 HTML 元素融合,并且会自动利用浏览器缓存、内置的图像优化和内存管理。它们允许你安全地显示来自任意来源的图像(下文 CORS 部分会详细介绍)。当图像必须适应使用 <canvas> 元素渲染的其他内容时,drawImage 非常有用。你还可以控制图像大小,并且在 CORS 策略允许的情况下,读取图像像素以进行进一步处理。最后,WebGL 为你提供了对图像最高程度的控制。你不仅可以读取像素并应用自定义图像算法,还可以使用 GLSL 进行硬件加速。

跨域资源共享 (CORS)

#

CORS 是一种浏览器用于控制一个站点如何访问另一个站点资源的机制。它的设计初衷是默认不允许一个网站使用 XHRfetch 向另一个站点发起 HTTP 请求。这可以防止其他网站上的脚本代表用户行事,并防止在未经许可的情况下访问另一个站点的资源。

在 Web 上,Flutter 使用 CanvasKit 或 skwasm(使用 Wasm 时)渲染器来渲染应用。这两者都依赖于 WebGL。WebGL 需要访问原始图像数据(字节)才能渲染图像。因此,图像必须来自已配置 CORS 策略并与托管你应用程序的域配合工作的服务器。

解决方案

#

Flutter 中有多种解决 CORS 限制的方法。

内存图像、资源图像和同源网络图像

#

如果应用已在内存中拥有编码后的图像字节,或者该图像是作为 资源 (asset) 提供的,亦或是存储在托管该应用的同一服务器上(也称为同源),则无需额外操作。可以使用 Image.memoryImage.assetImage.network 来显示图像。

在开启了 CORS 的 CDN 上托管图像

#

通常,内容分发网络 (CDN) 可以配置为自定义允许哪些域访问你的内容。例如,Firebase 站点托管允许在 firebase.json 文件中指定自定义 Access-Control-Allow-Origin 请求头。

如果无法控制源服务器,请使用 CORS 代理

#

如果图像服务器无法配置为允许来自你应用程序的 CORS 请求,你仍然可以通过代理服务器转发请求来加载图像。这要求中间服务器具有足够的访问权限来加载这些图像。

当原始图像服务器公开提供图像,但未配置正确的 CORS 请求头时,可以使用此方法。

示例

使用 HTML 平台视图

#

如果其他解决方案都不适用于你的应用,Flutter 支持使用 HtmlElementView 在应用内嵌入原始 HTML。你可以使用它创建一个 <img> 元素来渲染来自其他域的图像。