在 Web 中展示图片
Web 支持使用标准的 Image
widget 和更高级的 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 和同源网络图片
#如果图片在应用内存中有编码后的字节信息、或者以 asset 的方式提供、或者和应用存储在同一服务器上(也就是同源),则不需要做额外工作。图片可以使用
Image.memory
、Image.asset
或 Image.network
来展示。
在支持 CORS 的 CDN 中托管图片
#通常,可以配置内容分发网络 (CDN) 来自定义哪些域名可以访问你的内容。例如:Firebase 站点托管允许在 firebase.json
文件中,
指定一个自定义的 Access-Control-Allow-Origin
头。
如果无法控制源服务器,则使用 CORS 代理
#如果无法从你的应用层面去配置图片服务器的 CORS,你依然可以通过另一个服务器代理请求,从而加载图片。这要求中转服务器对图片加载有充分的访问权。
此方法适用于源图片服务器公开提供了图片,却没有正确配置 CORS 头的情况。
例子:
使用 HTML 原生平台视图
#如果其他解决方案都不适合你的应用,
Flutter 还支持在应用中使用 HtmlElementView
嵌入原始的 HTML。通过它可以创建一个 <img>
元素来渲染另一个域名的图片。
除非另有说明,本文档之所提及适用于 Flutter 的最新稳定版本,本页面最后更新时间: 2024-10-02。 查看文档源码 或者 为本页面内容提出建议。