Reputation: 1891
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?
Upvotes: 113
Views: 126069
Reputation: 1671
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:
Open the GCP console, select your project and start a cloud terminal session by clicking the >_ icon button in the top navbar.
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.
Go to your firebase console and open firebase storage there you find gs://
Run gsutil cors set cors.json gs://your-bucket
If you need more information: https://cloud.google.com/storage/docs/configuring-cors
Upvotes: 145
Reputation: 4844
There are a number of answers here about --web-renderer html
, but this is not a good technical decision.
As a solution, the Flutter team also suggests (in addition to customizing cors in various ways):
The last item may be the most successful if you are configured to use Image.network
. This is also quite handy if you are hosting your project on services like Github Pages.
All of these ways also mean that:
The image can be displayed using
Image.memory
,Image.asset
, andImage.network
in both HTML and CanvasKit modes.
You can read about all the methods here - Displaying images on the web | Flutter
Upvotes: 1
Reputation: 20379
There are two ways to resolve this either run your app using HTML renderer or set up the CORS configuration.
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
cors.json
and add this json content, which will remove all domain restrictions. (It doesn't matter where this file is located)[
{
"origin": ["*"],
"method": ["GET"],
"maxAgeSeconds": 3600
}
]
gcloud init
(located in google-cloud-sdk/bin
)gsutil cors set cors.json gs://<your-bucket-name>.appspot.com
You can find your bucket name in firebase storage.I have documented this entire process in github gists
Upvotes: 104
Reputation: 8725
This answer includes the two main ones mentioned as well as a vital point that wasn't:
Select and open your launch config:
Note the args
value:
{
"version": "0.2.0",
"configurations": [
{
"name": "Flutter (lib\\main.dart)",
"type": "dart",
"request": "launch",
"program": "lib\\main.dart",
"flutterMode": "profile",
"args": ["-d", "chrome", "--web-renderer", "html"]
}
]
}
Make sure you're running the same config:
Now you can run the app as usual.
Install gsutil
and create a file cors.json
with content:
[
{
"origin": ["*"],
"method": ["GET"],
"maxAgeSeconds": 3600
}
]
Run gsutil cors set cors.json gs://[YOUR BUCKET]
. If you later want to clear this config from your bucket change the content to []
and run again.
This is what made it work for my rules that required authentication, as I have removed the token param from the image url. Get the user auth token (FirebaseAuth.instance.currentUser.getIdToken()
) and add it to the headers arg like so:
NetworkImage(imageUrl, headers: {
'Authorization': 'Bearer $token',
})
Not sure what your particular situation is with "another domain" but I hope this is relevant.
Upvotes: 5
Reputation: 2137
This issue will occur by CROS policy. and There is two case to handle this:
For Debugging I suggest just disable the web Security to Pass through CROS. or use flutter_cors package. This package only work for debugging.
For Publishing, I suggest use Proxy server to handle the CORS issue.It is a best way to Bypass CORS. Or You can try some other methods -Link Here
Upvotes: 0
Reputation: 498
If you use Firebase storage just follow these steps:
Open Google Cloud Console at your project.
Click on console icon in top right corner.
Click Open editor.
Click File->New->cors.json.
Place code below:
[
{
"origin": ["*"],
"method": ["GET"],
"maxAgeSeconds": 3600
}
]
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.
Upvotes: 31
Reputation: 141
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:
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
.
Open chrome.dart
in your text editor.
Add '--disable-web-security'
under the like '--disable-extensions'
and save the file.
Run flutter clean
in your project folder and run the app.
Adding this flag might also cause some security issues.
Upvotes: 1
Reputation: 1116
There are two ways to solve this issue:
Just run your flutter web with
flutter run -d chrome --web-renderer html
But there is one problem when you render your canvas view to HTML view. All your views like images, text, etc. will come out blurry (bad quality). If you can sacrifice the quality, go on with the first solution.
If you don't want to sacrifice quality, you need to add some code to your backend site. I have done with NodeJS, you can use with yours:
var express = require("express")
var app = express()
var subsriberRecord = require("./controller/Subscribe")
var blogRecord = require("./controller/BlogContent")
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();
});
app.use("/record/", subsriberRecord);
app.use("/record/", blogRecord);
app.use('/uploads', express.static('./uploads'));
app.listen(5000, () => {
console.log("Server running at port 5000");
})
Upvotes: -1
Reputation: 448
For me this worked:
flutter run -d chrome --web-renderer html
Upvotes: 31
Reputation: 722
Simply add this in your Flutter (web/index.html
):
<script type="text/javascript">
window.flutterWebRenderer = "html";
</script>
Upvotes: 37
Reputation: 1891
I solved this issue by using html renderer:
flutter build web --release --web-renderer html
or
flutter run --web-renderer html
Upvotes: 58
Reputation: 537
The Ultimate Solution
Use this package instead of flutter's NetworkImage.
https://pub.dev/packages/image_network
Tested on Flutter web with Canvas renderer and it works like a charm!
Upvotes: 10
Reputation: 127
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
Upvotes: 4
Reputation: 10539
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
Upvotes: 11
Reputation: 1160
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 *
Upvotes: 1
Reputation: 11941
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,
);
}
}
Upvotes: 9