【问题标题】:Flutter web 无法从另一个域加载网络图像
【发布时间】:2021-04-15 14:59:53
【问题描述】:

我无法通过 API 调用从其他域加载 Flutter Web 中的网络图像。收到此错误

试图从另一个域加载图像?在以下位置找到答案: https://flutter.dev/docs/development/platform-integration/web-images ImageCodecException: 加载网络图片失败。

有什么帮助吗?

【问题讨论】:

标签: flutter flutter-web


【解决方案1】:

为了能够在 Flutter 网页上显示来自任何其他域或 Firebase 存储的图像,您必须为 CORS 配置数据。

  1. 打开GCP console,选择您的项目并通过单击顶部导航栏中的>_ 图标按钮启动云终端会话。

  2. 点击打开编辑器按钮(铅笔图标),然后创建cors.json 文件。

cors.json 文件应如下所示:

[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]

我将原点设置为*,这意味着每个网站都可以显示您的图像。但您也可以在此处插入您网站的域来限制访问。

  1. 运行gsutil cors set cors.json gs://your-bucket

如果您需要更多信息:https://cloud.google.com/storage/docs/configuring-cors

【讨论】:

  • 在第 2 步中,为了创建 cors.json 文件,单击与 Explorer:XXXX 同一行的 3 个点 (...) 或单击文件>新文件。第 3 步:您将在 Firebase STORAGE 控制台中找到“your-bucket”,当您运行 shell 命令时,您必须授权。
  • 验证:gsutil cors get gs://your-bucket
  • 感谢 Jens 和 Spuka,这真的救了我 - 不知道你到底从哪里得到的解决方案
  • 在上述所有建议之后仍然无法正常工作,尝试在我的颤振网络应用中显示 YouTube 缩略图。在第 3 点之后我是否遗漏了什么?是否需要执行任何重新加载或刷新命令。请给我建议。
  • 这看起来像是只与 firebase 和 google cloud 相关的配置。颤振应用程序中是否还涉及任何其他配置?由于图像仍未加载并引发缺少 CORS 标头错误。
【解决方案2】:

有两种方法可以解决此问题,使用 HTML 渲染运行您的应用程序或设置 CORS 配置。

1。使用 HTML 渲染

Taken from the docs

CORS 是浏览器用来控制一个站点如何访问另一个站点的资源的一种机制。它的设计是这样的,默认情况下,一个网站不允许使用 XHR 或 fetch 向另一个网站发出 HTTP 请求。这可以防止另一个站点上的脚本代表用户执行操作,并在未经许可的情况下访问另一个站点的资源

当使用 时,当浏览器知道图像来自另一个站点并且 CORS 策略不允许访问数据时,它会自动阻止对像素的访问。

Flutter 有两个 web 渲染器,canvaskit 和 html 当您在 Flutter Web 上运行/构建应用程序时,它会使用基于其运行设备的渲染器。

HTML 渲染器:当应用在移动浏览器中运行时。

CanvasKit 渲染器:当应用在桌面浏览器中运行时。

自动(默认) - 自动选择要使用的渲染器。

HTML 渲染器无需额外配置即可加载跨域图像。 因此您可以使用这些命令来运行和构建应用程序。

flutter run -d chrome --web-renderer html // to run the app

flutter build web --web-renderer html --release // to generate a production build

来源:https://docs.flutter.dev/development/tools/web-renderers

2。设置CORS Configuration

  • 下载Google-cloud-sdk,其中包含一个名为 gsutil 的工具
  • 在您的 Flutter 项目中创建一个名为 cors.json 的文件并添加此 json 文件,该文件将删除所有域限制。
[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]
  • 运行 gcloud init // 位于 google-cloud-sdk/bin 中
  • 通过单击链接并在控制台中选择项目进行身份验证
  • 最后执行gsutil cors set cors.json gs://<your-bucket-name>.appspot.com你可以在firebase storage中找到你的bucket名称。

【讨论】:

    【解决方案3】:

    我通过使用 html 渲染器解决了这个问题

    flutter build web --release --web-renderer html
    

    flutter run --web-renderer html

    【讨论】:

    • 它适用于部署和调试
    • 不为 Flutter Web 的 Google Places API 加载
    • 它会使图像和文本的密度如此糟糕......请不要使用那种类型的渲染
    【解决方案4】:

    对我来说flutter run -d chrome --web-renderer html 工作。

    【讨论】:

    • 参数在部署时有效。您只需要在构建过程中添加相同的参数flutter build web --web-renderer html
    【解决方案5】:

    如果您使用 Firebase 存储,请按照以下步骤操作:

    1. 在您的项目中打开Google Cloud Console
    2. 点击右上角的控制台图标
    3. 点击打开编辑器
    4. 点击文件->新建->cors.json
    5. 在下面输入代码
    [
      {
        "origin": ["*"],
        "method": ["GET"],
        "maxAgeSeconds": 3600
      }
    ]
    
    1. 然后在控制台中运行

    **

    gsutil cors set cors.json gs://bucket-name

    **

    bucket-name 是存储桶的名称,您可以在 firebase 项目的存储部分文件夹上方找到该名称

    【讨论】:

    • 这对我有用。谢谢你:)
    【解决方案6】:

    如果您无法更新 CORS 设置或添加代理,请选择 CanvasKit(性能更好)而不是 HTML 渲染器 - 可以使用 platform view 显示图像:

    import 'dart:html';
    import 'package:flutter/material.dart';
    import 'dart:ui' as ui;
    
    class MyImage extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {
        String imageUrl = "image_url";
        // https://github.com/flutter/flutter/issues/41563
        // ignore: undefined_prefixed_name
        ui.platformViewRegistry.registerViewFactory(
          imageUrl,
          (int _) => ImageElement()..src = imageUrl,
        );
        return HtmlElementView(
          viewType: imageUrl,
        );
      }
    }
    
    
    

    【讨论】:

    • 我想添加像图像小部件这样的 fit 属性,知道如何添加吗?
    【解决方案7】:

    它似乎通过运行flutter run --web-renderer html解决了我的问题

    【讨论】:

    • 每次在 Flutter 中复制更改时都会执行此命令?,此命令有效,但重新执行更改时不再有效
    【解决方案8】:

    只需在 web 文件夹中添加 cors.json

    [
      {
        "origin": ["*"],
        "method": ["GET"],
        "maxAgeSeconds": 3600
      }
    ]
    

    【讨论】:

    • @MuthuS 你找到解决方案了吗?
    • 不,不幸的是,在我的情况下没有解决方案。幸运的是它是我的内部项目,所以我曾经为用户浏览器启用 CORS 插件以使其工作。
    • 这是一个很好的答案。在我的颤振项目中像魅力一样工作。为什么它没有更多的赞成票?我错过了什么吗?
    • 在我的情况下不起作用
    【解决方案9】:

    为了快速调试,您也可以在运行配置中添加参数--web-renderer html,而不是从终端运行flutter run -d chrome --web-renderer html。在菜单栏上,浏览Run > Edit Configurations

    【讨论】:

      【解决方案10】:

      有两种方法可以解决这个问题:

      1- 只需使用 flutter run -d chrome --web-renderer html

      运行您的 Flutter Web

      但是,当您将画布视图渲染为 HTML 视图时,会出现一个问题。因此,您的所有视图(例如图像,文本等)都变得模糊(质量差)。如果您牺牲质量,请继续使用第一个解决方案。

      1. 如果您不牺牲质量,那么您需要向您的后端站点添加一些代码,我已经使用 node js 完成了您可以与您的站点一起使用。
      app.use(function(req, res, next) {
          res.header("Access-Control-Allow-Origin", "*");
          res.header("Access-Control-Allow-Headers",
           "Origin, X-Requested-With, Content-Type, Accept"
           );
          next();
        });
      

      所以,我选择了第二种解决方案,因为我不牺牲质量。因此,我为您提供了我的后端屏幕截图,以便您更好地理解希望您找到了解决方案。

      【讨论】:

        【解决方案11】:

        对于使用 Slim 框架的人,只需在该文件夹上创建一个 .htaccess 文件用于存储图像并放入这行代码

        Header set Access-Control-Allow-Origin *
        

        【讨论】:

          【解决方案12】:

          我从其他域加载内容时遇到问题,我无法控制从服务器端更改 cors 设置。我找到了解决这个问题的方法。

          步骤 1:转到 C:\src\flutter\packages\flutter_tools\lib\src\web 或从您的 Flutter 根目录导航到 flutter\packages\flutter_tools\lib\src\web

          第 2 步:在文本编辑器中打开 chrome.dart。

          第三步:在'--disable-extensions'点赞下添加'--disable-web-security'作为保存文件。

          第 4 步:在您的项目文件夹中运行 flutter clean 并运行应用程序。

          希望这对你有用。
          我还没有在生产中测试我的应用程序。添加此标志也可能会导致一些安全问题。

          【讨论】:

            猜你喜欢
            • 2021-06-05
            • 1970-01-01
            • 2021-06-06
            • 1970-01-01
            • 1970-01-01
            • 2021-10-18
            • 2021-01-31
            • 2020-06-16
            • 2021-01-10
            相关资源
            最近更新 更多