在 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 限制。
内存图片、资源图片和同源网络图片
#如果应用内存中存在已编码图片的字节、作为资源提供,或者存储在服务应用的同一服务器上(也称为同源),则无需额外的工作。图片可以使用 Image.memory
、Image.asset
或 Image.network
显示。
在支持 CORS 的 CDN 中托管图片
#通常,内容分发网络 (CDN) 可以配置为自定义允许哪些域访问你的内容。例如,Firebase 网站托管允许在 firebase.json
文件中指定自定义的 Access-Control-Allow-Origin
标头。
如果无法控制源服务器,请使用 CORS 代理
#如果图片服务器无法配置为允许来自你应用的 CORS 请求,你仍然可以通过另一个服务器代理请求来加载图片。这需要中间服务器有足够的权限来加载图片。
当原始图片服务器公开提供图片但未配置正确的 CORS 标头时,可以使用此方法。
示例
使用 HTML 平台视图
#如果以上解决方案都不适用于你的应用,Flutter 支持使用 HtmlElementView
在应用内部嵌入原始 HTML。使用它来创建 <img>
元素以从另一个域渲染图片。