跳至主要内容

在 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 限制。

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

#

如果应用程序在内存中具有编码图像的字节,作为 资源 提供,或存储在提供应用程序的同一服务器上(也称为同源),则无需额外的努力。可以使用 Image.memoryImage.assetImage.network 显示图像。

在支持 CORS 的 CDN 中托管图像

#

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

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

#

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

此方法可用于原始图像服务器公开提供图像但未配置正确的 CORS 标头的情况。

示例

使用 HTML 平台视图

#

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