How to support HTTP headers NetworkImage in flutter web

2,227

Solution 1

With cached_network_image: 3.0.0 I got it working to add headers by using the CachedNetworkImageProvider class.

CachedNetworkImageProvider(
              "${IOConfig.apiUrl}",
              headers: {"Authorization": "Bearer $apiToken",
                "Access-Control-Allow-Headers": "Access-Control-Allow-Origin, Accept"}                                                
             ,imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet)

I had to start it with an argument to change the web-renderer

flutter run -d chrome --web-renderer html 

Solution 2

Most likely, this particular limitation is due to the reduced customization capabilities of the img HTML-element itself. Fortunately, there are many other ways to display network images - here are just two examples:

Using http package:

  void loadImageV1(String url, Map<String, String>? headers) async {
    final res = await http.get(Uri.parse(url), headers: headers);
    final blob = html.Blob([res.bodyBytes]);
    setState(() {
      _url = html.Url.createObjectUrlFromBlob(blob);
    });
  }

or using exposed by browser fetch API:

  void loadImageV2(String url, Map<String, String>? headers) async {
    final res = await html.window.fetch(url, {'method': 'GET', 'headers': headers});
    final blob = await res.blob();
    setState(() {
      _url = html.Url.createObjectUrlFromBlob(blob);
    });
  }

And now we can use generated syntetic url with Image.Network constructor.

Here is full demo:

import 'dart:html' as html;
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';

void main() => runApp(DemoApp());

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Network Image Demo',
      home: NextLabPage(),
    );
  }
}

const imgUrl = 'https://robohash.org/1234';
const imgHeaders = {'Accept': 'image/*', 'Accept-language': 'en'};

class NextLabPage extends StatefulWidget {
  @override
  _NextLabPageState createState() => _NextLabPageState();
}

class _NextLabPageState extends State<NextLabPage> {
  String? _url;

  @override
  void initState() {
    super.initState();
    loadImageV1(imgUrl, imgHeaders);
  }

  @override
  void dispose() {
    if (_url != null) html.Url.revokeObjectUrl(_url!);
    super.dispose();
  }

  void loadImageV1(String url, Map<String, String>? headers) async {
    final res = await http.get(Uri.parse(url), headers: headers);
    final blob = html.Blob([res.bodyBytes]);
    setState(() {
      _url = html.Url.createObjectUrlFromBlob(blob);
    });
  }

  void loadImageV2(String url, Map<String, String>? headers) async {
    final res = await html.window.fetch(url, {'method': 'GET', 'headers': headers});
    final blob = await res.blob();
    setState(() {
      _url = html.Url.createObjectUrlFromBlob(blob);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: _url != null ? Image.network(_url!) : Text('Loading...'),
      ),
    );
  }
}

Share:
2,227
Naeim Lotfali
Author by

Naeim Lotfali

Hi there, I am Naeim Lotfali I started programming in 2016 with C++, Java, and later Python. Then I decided to choose my profession, so I started learning mobile application development with Java to write Android native applications in 2018 (later I started learning Kotlin to do so). I like to learn new technologies, that is why I have started my Flutter development journey in 2019. I am totally engaged with Flutter and now I am trying to understand it deeply. Also as I like to learn new technologies, I have minor experience in Intelligent Routing with different algorithms. "Greedy for Science"

Updated on November 23, 2022

Comments

  • Naeim Lotfali
    Naeim Lotfali over 1 year

    I tried to get some images from the internet in flutter web that need to add headers. I've used cached_network_image: ^2.5.1 and it doesn't support the web completely also Image.network seems when running flutter on the web, headers are not used. Both of these ways successfully work on the Android release. enter image description here

    environment:
      sdk: ">=2.7.0 <3.0.0"
    
    Doctor summary (to see all details, run flutter doctor -v):
    [√] Flutter (Channel stable, 2.0.4, on Microsoft Windows [Version 10.0.19042.985], locale en-US)
    [√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    [√] Chrome - develop for the web
    [√] Android Studio (version 4.1.0)
    [√] IntelliJ IDEA Ultimate Edition (version 2020.1)
    [√] Connected device (3 available)
    
    • No issues found!