简体   繁体   English

如何在 flutter web 中支持 HTTP 标头 NetworkImage

[英]How to support HTTP headers NetworkImage in flutter web

I tried to get some images from the internet in flutter web that need to add headers.我试图在 flutter web 中从互联网上获取一些需要添加标题的图像。 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.我使用了 cached_network_image: ^2.5.1 并且它不完全支持 web 在 web 上运行 flutter 时,Image.network 似乎也没有使用。 Both of these ways successfully work on the Android release.这两种方式都在 Android 版本上成功运行。 在此处输入图像描述

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!

With cached_network_image: 3.0.0 I got it working to add headers by using the CachedNetworkImageProvider class.使用cached_network_image: 3.0.0我可以使用 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 

Most likely, this particular limitation is due to the reduced customization capabilities of the img HTML-element itself.最有可能的是,这种特殊的限制是由于img HTML 元素本身的定制能力降低。 Fortunately, there are many other ways to display network images - here are just two examples:幸运的是,还有许多其他方法可以显示网络图像 - 这里只是两个示例:

Using http package:使用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 :或使用浏览器获取 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.现在我们可以使用生成的合成 url 和Image.Network构造函数。

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...'),
      ),
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM