在 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>
元素,以从另一个域渲染图片。