61

I can't load network images in flutter web from other domains with API calls. getting this error

Trying to load an image from another domain? Find answers at: https://flutter.dev/docs/development/platform-integration/web-images ImageCodecException: Failed to load network image.

any help?

Abel Ayalew
  • 1,155
  • 1
  • 6
  • 11

15 Answers15

84

For being able to display your images from any other Domain or from Firebase Storage on a Flutter web page you have to configure your data for CORS.

  1. Open the GCP console, select your project and start a cloud terminal session by clicking the >_ icon button in the top navbar.

  2. Click the open editor button (pencil icon), then create the cors.json file.

The cors.json file should look like this:

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

I set the origin to * which means that every website can display your images. But you can also insert the domain of your website there to restrict access.

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

If you need more information: https://cloud.google.com/storage/docs/configuring-cors

Deekshith Xetty
  • 133
  • 1
  • 9
Jens Becker
  • 1,011
  • 5
  • 11
  • 11
    On Step 2, in order to create the cors.json file, click on the 3 dots (...) on the same row as Explorer:XXXX OR just click on File>new file. Step 3: You'll find "your-bucket" in your firebase STORAGE console and YOU WILL HAVE TO AUTHORIZE when you run the shell command. – theSpuka Feb 21 '21 at 21:34
  • 5
    To verify: `gsutil cors get gs://your-bucket` – Liel van der Hoeven Jul 05 '21 at 22:31
  • Thanks Jens and Spuka, that really saved me - don't know where the hell you got that solution from – James 666 Jul 08 '21 at 18:18
  • 2
    Still not working after the all above suggestions, Trying to display YouTube thumbnails in my flutter web app. Am I missing something after point 3. Is there any reload or refresh command need to perform. Please suggest me. – Raghu Mudem Aug 03 '21 at 12:06
  • This looks like configuration only related to firebase and google cloud. Is there any additional configuration involved in flutter app as well? As images are still not loading and throws missing CORS headers error. – sh_ark Oct 07 '21 at 06:09
  • Okay, so it's working for me, I was running in localhost and also using origin as ```"https://firebasestorage.googleapis.com/v0/b/my_app_name.appspot.com"```, which on changing to ```"*"``` starts working. But how to correctly use cutom origin instead of ```"*"```? – sh_ark Oct 07 '21 at 07:35
  • @sh_ark use `https://my_app_name.we.app` this is the domain the request is coming from – nipunasudha Oct 23 '21 at 07:40
  • for people like me who don't know anything about buckets and get 403 errors, you get your bucket List with ```gsutil ls```, and check which one is used for your app and set cors.json for that one. – Ali Azimoshan Dec 16 '21 at 06:32
  • 1
    thank you so much. Wouldnt have figured this out in a million years lol – Hassan Hammad Apr 09 '22 at 22:11
58

There are two ways to resolve this either run your app using HTML render or setup the CORS configuration.

1. Using HTML render

Taken from the docs

CORS is a mechanism that browsers use to control how one site accesses the resources of another site. It is designed such that, by default, one web-site is not allowed to make HTTP requests to another site using XHR or fetch. This prevents scripts on another site from acting on behalf of the user and from gaining access to another site’s resources without permission

When using <img>, <picture>, or <canvas>, the browser automatically blocks access to pixels when it knows that an image is coming from another site and the CORS policy disallows access to data.

Flutter has two renderers for web, canvaskit and html When you run/build app on the flutter web it uses renderers based on the device where its running.

HTML renderer: when the app is running in a mobile browser.

CanvasKit renderer: when the app is running in a desktop browser.

auto (default) - automatically chooses which renderer to use.

The HTML renderer can load cross-origin images without extra configuration. so you could use these commands to run and build the app.

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

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

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

2. Setup CORS Configuration

  • Download the Google-cloud-sdk which contains a tool called gsutil
  • In your flutter project create a file called cors.json and add this json file which will remove all domain restrictions.
[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]
  • Run gcloud init // located in google-cloud-sdk/bin
  • Authenticate yourself by clicking the link and choose the project in the console
  • finally execute gsutil cors set cors.json gs://<your-bucket-name>.appspot.com You can find your bucket name in firebase storage.
Mahesh Jamdade
  • 11,710
  • 4
  • 79
  • 97
39

i solve this issue by using html renderer

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

or

flutter run --web-renderer html

Abel Ayalew
  • 1,155
  • 1
  • 6
  • 11
22

for me flutter run -d chrome --web-renderer html worked.

  • The arguments work when deployed. You just need to add the same arguments during build `flutter build web --web-renderer html` – Omatt Sep 11 '21 at 15:46
14

If you use firebase storage just follow these steps:

  1. Open Google Cloud Console at your project
  2. Click on console icon in top right corner
  3. Click Open editor
  4. Click File->New->cors.json
  5. Place code below
[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]
  1. Then Run in console

**

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

**

bucket-name is the name of the storage bucket which you can find on your firebase project above the folders in the storage section

F-Y
  • 300
  • 4
  • 12
5

To debug quickly, instead of flutter run -d chrome --web-renderer html running from the terminal you can also add the arguments --web-renderer html on your run config. On the menu bar, navigate through Run > Edit Configurations

Run config

Omatt
  • 5,027
  • 2
  • 25
  • 83
4

If you can't update CORS settings or add proxy, prefer CanvasKit (has better performance) over HTML renderer - could display image with 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,
    );
  }
}


Nuts
  • 8,789
  • 1
  • 31
  • 38
3

it seems it solved my issue by running flutter run --web-renderer html

carlosx2
  • 1,314
  • 12
  • 23
  • This command is executed every time a change is copied in Flutter ?, this command works but when re-executing the changes no longer work – Lenin Zapata Jun 22 '21 at 21:08
3

just add cors.json in web folder

[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]
Elmasry
  • 99
  • 1
  • 8
  • @MuthuS did you find the solution? – Raghu Mudem Aug 03 '21 at 12:18
  • No, unfortunately no solutions were worked in my case. Luckily its my internal project, so i used to enable CORS plug-in for users browsers to make it work. – Muthu S Aug 04 '21 at 17:00
  • This is a great answer. Worked like a charm in my flutter project. Why does it not have more upvotes? Am I missing anything? – Priyshrm Nov 16 '21 at 09:44
  • 2
    Did not work in my case – santosh adhikari Dec 12 '21 at 04:44
  • Adding cors.json in the web folder does not work by itself. You have to follow the instructions in other answers to apply the file to your storage bucket using gsutil. And it does not have to be in the web folder, it can be saved anywhere. – most200 Jun 02 '22 at 19:27
0

There is a two way to solve this issue :

1- Just run your flutter web with flutter run -d chrome --web-renderer html

But there is one problem when you renderer your canvas view to HTML view. So your all views like images, text, etc gone blurry(bad quality). If you sacrifice the quality so go on with the first solution.

  1. If you don't sacrifice quality so you need to add some code to your backend site I have done with node js you can use with yours.
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();
  });

So, I chose the second solution because I don't sacrifice quality. So I provide you with my backend screenshot for better understanding hope you found your solution.

Screenshot

HandyPawan
  • 894
  • 1
  • 10
  • 16
0

For someone who uses Slim Framework, just create a .htaccess file on that folder for storing images and put this line of code

Header set Access-Control-Allow-Origin *
NM Naufaldo
  • 831
  • 5
  • 16
0

I had an issue while loading content from other domains which I don't have control over to change the cors settings from the server-side. I have found a work around for this problem.

STEP 1: go to C:\src\flutter\packages\flutter_tools\lib\src\web or navigate from your flutter root directory to flutter\packages\flutter_tools\lib\src\web.

STEP 2: open chrome.dart in your text editor.

STEP 3: add '--disable-web-security' under the like '--disable-extensions' as save the file.

STEP 4: run flutter clean in your project folder and run the app.

Hope this works for you.
I haven't tested my application in production yet. Adding this flag might also cause some security issues.

CSR
  • 107
  • 12
0

Verified answer is correct, Upvoted you man. Here's how I did it

enter image description here

Muhammad Bilal
  • 1,502
  • 1
  • 16
  • 13
0

Simply.. in your flutter (web/index.html) add this:

enter image description here

Ehab Reda
  • 71
  • 1
  • 6
0

This official solution worked for me on Chrome only (Source). But I had to run it first every time.

flutter run -d chrome --web-renderer html

And disabling web security also worked (Source). But the browsers will show a warning banner.

But In case you are running on a different browser than Chrome (e.g. Edge) and you want to keep 'web security' enabled. You can change the default web renderer in settings in VS Code

File ==> Preferences ==> Settings ==> Enter 'Flutter Web' in the Search Bar ==> Set the default web renderer to html