在 Web 上显示图片
了解如何在网络上加载和显示图像。
网络支持标准的 Image 组件和更高级的 dart:ui/Image 类(当需要对图像显示进行更细粒度的控制时)。但是,由于 Web 浏览器旨在安全地运行不受信任的代码,因此与移动和桌面平台相比,您在使用图像时存在某些限制。本页解释了这些限制并提供了规避方法。
背景
#网络提供了几种显示图像的方法
每种选项都有其自身的优点和缺点。例如,内置元素可以很好地与其他 HTML 元素配合使用,并且可以自动利用浏览器缓存、内置图像优化和内存管理。它们允许您安全地显示来自任意来源的图像(有关更多信息,请参阅下面的 CORS 部分)。drawImage 非常适合图像必须适合使用 <canvas> 元素渲染的其他内容的情况。您还可以控制图像大小,并且在 CORS 策略允许的情况下,将图像的像素读回进行进一步处理。最后,WebGL 提供了对图像的最高程度的控制。您不仅可以读取像素并应用自定义图像算法,还可以使用 GLSL 进行硬件加速。
跨域资源共享 (CORS)
#
CORS 是一种浏览器用来控制一个站点如何访问另一个站点的资源的安全机制。它的设计目的是,默认情况下,一个网站不允许使用 XHR 或 fetch 向另一个站点发出 HTTP 请求。这可以防止其他站点上的脚本代表用户操作,并防止未经许可访问其他站点的资源。
在网络上,Flutter 使用 CanvasKit 或 skwasm(在使用 Wasm 时)渲染器渲染应用程序。两者都依赖于 WebGL。WebGL 需要访问原始图像数据(字节)才能渲染图像。因此,图像只能来自配置了 CORS 策略以与提供应用程序的域一起工作的服务器。
解决方案
#有多种解决方案可以解决 Flutter 中的 CORS 限制。
内存、资源和同源网络图像
#如果应用程序拥有编码图像的字节,作为 资源 提供,或存储在提供应用程序的同一服务器上(也称为同源),则无需额外操作。可以使用 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> 元素以从另一个域渲染图像。