Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

After upgrading to Flutter 3.27.0, the usage of CachedNetworkImage causes error: SecurityError: Failed to execute 'texImage2D' on 'WebGL2RenderingContext': The image element contains cross-origin data, and may not be loaded. #995

Closed
1 task
rednikisfun opened this issue Dec 12, 2024 · 20 comments

Comments

@rednikisfun
Copy link

rednikisfun commented Dec 12, 2024

🐛 Bug Report

I've upgraded my project's Flutter version to 3.27.0, and now, when I run the web version, I get a lot of errors like this:

canvaskit.js:21 Uncaught (in promise) SecurityError: Failed to execute 'texImage2D' on 'WebGL2RenderingContext': The image element contains cross-origin data, and may not be loaded.

UPD: Since in my project, CachedNetworkImage is heavily used, and there are quite a lot of images, too much Failed to execute 'texImage2D' on 'WebGL2RenderingContext causes Additional error: RuntimeError: memory access out of bounds and overall crash of the app.

Expected behavior

It should load an image normally, like it used to in the previous Flutter versions

Reproduction steps

  1. Create a project with flutter version 3.27.0
  2. Use CachedNetworkImage
  3. Run project in web

Configuration

Version: 3.4.1

Platform:

  • :web
@rednikisfun rednikisfun changed the title After upgrading to Flutter 3.27.0, the usage of CachedNetworkImage causes error: After upgrading to Flutter 3.27.0, the usage of CachedNetworkImage causes error: SecurityError: Failed to execute 'texImage2D' on 'WebGL2RenderingContext': The image element contains cross-origin data, and may not be loaded. Dec 12, 2024
@rednikisfun
Copy link
Author

rednikisfun commented Dec 12, 2024

Changing from:

CachedNetworkImage( imageUrl: slides[itemIndex].image.desktop.fromStringLang(lang), fit: BoxFit.cover, alignment: Alignment.center, ),

to

CachedNetworkImage( imageUrl: slides[itemIndex].image.desktop.fromStringLang(lang), imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet, // <-- Add this line fit: BoxFit.cover, alignment: Alignment.center, ),

seems to solve the problem provisionally

@lordarcadius
Copy link

Changing from:

CachedNetworkImage( imageUrl: slides[itemIndex].image.desktop.fromStringLang(lang), fit: BoxFit.cover, alignment: Alignment.center, ),

to

CachedNetworkImage( imageUrl: slides[itemIndex].image.desktop.fromStringLang(lang), imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet, // <-- Add this line fit: BoxFit.cover, alignment: Alignment.center, ),

seems to solve the problem provisionally

I am not able to import "ImageRenderMethodForWeb". It says undefined name. Can you share the import path?

@rednikisfun
Copy link
Author

rednikisfun commented Dec 12, 2024

@lordarcadius

I am not able to import "ImageRenderMethodForWeb". It says undefined name. Can you share the import path?

Right, forgot to mention, you need to use import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart'; for it to have access to ImageRenderMethodForWeb.

I've also forked the cached_network_image package, and set the ImageRenderMethodForWeb.HttpGet as default. If your project heavily relies on cached_network_image, I would recommend to temporarily use this fork until flutter_cached_network_image team roll out a fix.

I've also created a PR, if they accept it, the ImageRenderMethodForWeb.HttpGet will be set by default.

@eduardofcr
Copy link

same problem after upgrade flutter to 3.27.0

@ZiyadF296
Copy link

ZiyadF296 commented Dec 16, 2024

@lordarcadius

I am not able to import "ImageRenderMethodForWeb". It says undefined name. Can you share the import path?

Right, forgot to mention, you need to use import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart'; for it to have access to ImageRenderMethodForWeb.

I've also forked the cached_network_image package, and set the ImageRenderMethodForWeb.HttpGet as default. If your project heavily relies on cached_network_image, I would recommend to temporarily use this fork until flutter_cached_network_image team roll out a fix.

I've also created a PR, if they accept it, the ImageRenderMethodForWeb.HttpGet will be set by default.

Hey; how did you add this fork to your pubspec.yaml exactly? @lordarcadius

@rednikisfun
Copy link
Author

@ZiyadF296

cached_network_image:
git:
url: https://github.com/Neotech-iHoops/flutter_cached_network_image.git
ref: develop
path: cached_network_image

@djol
Copy link

djol commented Dec 19, 2024

While @rednikisfun's fix works, it ? seems to cause a new error under Safari (v18.2) (works fine with Chrome). When an image isn't found, the errorWidget does not seem to be used / in my case the placeholder widget (I'm using a CircularProgressIndicator()) instead persists. Prior to the 3.27.0 bug, this worked fine across all browsers.

Screenshot 2024-12-19 at 12 39 41 pm

@ZiyadF296
Copy link

ZiyadF296 commented Dec 19, 2024 via email

@martin-bautista-nimble
Copy link

Do we have an ETA For that fix? @ZiyadF296

@ZiyadF296
Copy link

ZiyadF296 commented Dec 19, 2024

@martin-bautista-nimble

It was mentioned here.

Flutter PR #160127 should solve it. You can track this PR until it reaches your branch, but it'll probably be pushed directly to stable.

@tfozo
Copy link

tfozo commented Dec 21, 2024

so i created a new file called cross_origin.dart in it

import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:web/web.dart' as web;

class CrossOriginNetworkImage extends ImageProvider<CrossOriginNetworkImage> {
  final String url;

  CrossOriginNetworkImage(this.url);

  @override
  Future<CrossOriginNetworkImage> obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture(this);
  }

  @override
  ImageStreamCompleter loadImage(
      CrossOriginNetworkImage key, ImageDecoderCallback decode) {
    final completer = Completer<ImageInfo>();

    final imageElement = web.HTMLImageElement()
      ..src = url
      ..crossOrigin = 'anonymous';

    imageElement.onLoad.listen((_) async {
      final canvas = web.HTMLCanvasElement();
      canvas.width = imageElement.width;
      canvas.height = imageElement.height;

      final ctx = canvas.context2D;
      ctx.drawImage(imageElement, 0, 0);

      // Convert canvas to a data URL and extract bytes.
      final dataUrl = canvas.toDataUrl('image/png');

      final bytes = UriData.parse(dataUrl).contentAsBytes();

      // Decode image bytes into a Flutter ui.Image.
      final codec = await ui.instantiateImageCodec(Uint8List.fromList(bytes));
      final frame = await codec.getNextFrame();

      completer.complete(ImageInfo(image: frame.image, scale: 1.0));
    });

    imageElement.onError.listen((_) {
      completer.completeError(Exception("Failed to load image: $url"));
    });

    return OneFrameImageStreamCompleter(completer.future);
  }
}

and then I replaced all my images that were using CachedImageNetworks with

CachedNetworkImage(
                                        imageUrl: _images[index].imageUrl!,
                                        fit: BoxFit.cover,
                                        imageBuilder: (context, imageProvider) {
                                          return Image(
                                            image: CrossOriginNetworkImage(
                                                _images[index].imageUrl!),
                                            fit: BoxFit.cover,
                                          );
                                        },
                                        placeholder: (context, url) => Center(
                                          child: SpinKitPulse(
                                            color: Colors.amber[100],
                                            size: 50.0,
                                          ),
                                        ),
                                        errorWidget: (context, url, error) =>
                                            const Icon(Icons.error),
                                      )

the only change i made is the imageBuilder attribute

it should fix it but I honestly don't know how it fixed it.
I'm waiting for a fix from CachedNetworkImage but until that is implemented i just use this to work on my other features.

@AndreiMisiukevich
Copy link

@tfozo, the fix is in Flutter, and it should be included in the next stable release. I saw a cherry-pick.

@tfozo
Copy link

tfozo commented Dec 21, 2024

@AndreiMisiukevich now what do I do?

Edit: Ahh, I'll keep an eye out for the update. Thanks again!

@AndreiMisiukevich
Copy link

@AndreiMisiukevich now what do I do?

Edit: Ahh, I'll keep an eye out for the update. Thanks again!

I'd propose to stick to the previous stable version until it's resolved - as we did 👍

@nekomaruh
Copy link

nekomaruh commented Dec 23, 2024

It's a weird behavior, my web page broke in production without even notice. Meanwhile had to switch to Image.network.

@vidhi002
Copy link

vidhi002 commented Jan 1, 2025

same issue

@AhabLives
Copy link

The issue is related to the CanvasKit Web Renderer (3.27.1)
"flutter run -d chrome --web-renderer html" will fix the problem locally.
I have not tested build/deploy with "html".

@rafalplonka
Copy link

The html renderer will be removed though

flutter/flutter#145954 (comment)

@nikb7
Copy link

nikb7 commented Jan 15, 2025

Flutter 3.27.2 has fixed this issue.

@rednikisfun
Copy link
Author

I've upgraded to 3.27.2, and the latest cached_network_image: ^3.4.1 package is working without issues, therefore, I am closing the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests