【问题标题】:Best way to set default header for all request in flutter http request在flutter http请求中为所有请求设置默认标头的最佳方法
【发布时间】:2019-06-16 16:18:21
【问题描述】:

对不起,如果这个问题太简单了,但我是新手,最近找不到在 HTTP 请求中设置默认标头的好方法,我可以扩展类或为其包装一个函数,但不应该有一种内置的简单方法,但我在文档中找不到它。

【问题讨论】:

    标签: http dart header flutter


    【解决方案1】:

    这可以通过 Dio 包轻松实现。

    https://pub.dartlang.org/packages/dio

    更新

    基于新的 Dio API:

    var dio = Dio();
    dio.interceptors.add(InterceptorsWrapper(onRequest: (RequestOptions options) async {
      var customHeaders = {
        'content-type': 'application/json'
        // other headers
      };
      options.headers.addAll(customHeaders);
      return options;
    }));
    
    Response response = await dio.get("url");
    print(response.data.toString());
    

    请参阅documentation 了解更多详情。

    【讨论】:

    • 中途拦截我真的很喜欢这个解决方案,它是最简单的方法
    • 这个 dio 对象会在我的所有小部件之间共享吗?如果没有,这个设置只会影响这个 dio 对象。
    • 这个包有一个破坏性错误,如果服务器抛出一个>= 400,就会抛出一个无法捕获的异常。
    【解决方案2】:
    import 'package:http/http.dart' as http;
    
    class MyClient extends http.BaseClient{
      http.Client _httpClient = new http.Client();
    
      MyClient(Map defaultHeaders);
    
      @override
      Future<http.StreamedResponse> send(http.BaseRequest request) {
        request.headers.addAll(defaultHeaders);
        return _httpClient.send(request);
      }
    }
    

    【讨论】:

    • 您不需要实例化另一个 Http 客户端。返回request.send() 也可以:)
    • @GuilhermeV。如果这样做,您将在每个请求上创建一个新的 http 客户端,而不是重新使用现有的客户端,这可能是一个持久连接。
    【解决方案3】:

    注册自定义HttpClientFactory

    Dart 允许注册工厂以创建 HttpClient

    class MyHttpOverrides extends HttpOverrides {
      @override
      HttpClient createHttpClient(SecurityContext context) {
        return new MyHttpClient(super.createHttpClient(context));
      }
    }
    
    void main() {
      HttpOverrides.global = new MyHttpOverrides();
      runApp(MyApp());
    }
    

    实现自定义HttpClient

    实现这样的自定义HttpClient 似乎过于复杂,但也许有更好的方法。

    该类从dart:io 及其所有抽象类实现HttpClient。

    方法get(...) 和getUrl(...) 被自定义为使用_updateHeaders(...) 添加自定义标头。您需要将其扩展到所有其他方法,例如 head、headUrl、open、post、...

    import 'dart:io';
    
    class MyHttpClient implements HttpClient {
      HttpClient _realClient;
    
      MyHttpClient(this._realClient);
    
      @override
      bool get autoUncompress => _realClient.autoUncompress;
    
      @override
      set autoUncompress(bool value) => _realClient.autoUncompress = value;
    
      @override
      Duration get connectionTimeout => _realClient.connectionTimeout;
    
      @override
      set connectionTimeout(Duration value) =>
          _realClient.connectionTimeout = value;
    
      @override
      Duration get idleTimeout => _realClient.idleTimeout;
    
      @override
      set idleTimeout(Duration value) => _realClient.idleTimeout = value;
    
      @override
      int get maxConnectionsPerHost => _realClient.maxConnectionsPerHost;
    
      @override
      set maxConnectionsPerHost(int value) =>
          _realClient.maxConnectionsPerHost = value;
    
      @override
      String get userAgent => _realClient.userAgent;
    
      @override
      set userAgent(String value) => _realClient.userAgent = value;
    
      @override
      void addCredentials(
              Uri url, String realm, HttpClientCredentials credentials) =>
          _realClient.addCredentials(url, realm, credentials);
    
      @override
      void addProxyCredentials(String host, int port, String realm,
              HttpClientCredentials credentials) =>
          _realClient.addProxyCredentials(host, port, realm, credentials);
    
      @override
      void set authenticate(
              Future<bool> Function(Uri url, String scheme, String realm) f) =>
          _realClient.authenticate = f;
    
      @override
      void set authenticateProxy(
              Future<bool> Function(
                      String host, int port, String scheme, String realm)
                  f) =>
          _realClient.authenticateProxy = f;
    
      @override
      void set badCertificateCallback(
              bool Function(X509Certificate cert, String host, int port)
                  callback) =>
          _realClient.badCertificateCallback = callback;
    
      @override
      void close({bool force = false}) => _realClient.close(force: force);
    
      @override
      Future<HttpClientRequest> delete(String host, int port, String path) =>
          _realClient.delete(host, port, path);
    
      @override
      Future<HttpClientRequest> deleteUrl(Uri url) => _realClient.deleteUrl(url);
    
      @override
      void set findProxy(String Function(Uri url) f) => _realClient.findProxy = f;
    
      @override
      Future<HttpClientRequest> get(String host, int port, String path) =>
          _updateHeaders(_realClient.get(host, port, path));
    
      Future<HttpClientRequest> _updateHeaders(
          Future<HttpClientRequest> httpClientRequest) async {
        return (await httpClientRequest)..headers.add('foo', 'bar');
      }
    
      @override
      Future<HttpClientRequest> getUrl(Uri url) =>
          _updateHeaders(_realClient.getUrl(url.replace(path: url.path)));
    
      @override
      Future<HttpClientRequest> head(String host, int port, String path) =>
          _realClient.head(host, port, path);
    
      @override
      Future<HttpClientRequest> headUrl(Uri url) => _realClient.headUrl(url);
    
      @override
      Future<HttpClientRequest> open(
              String method, String host, int port, String path) =>
          _realClient.open(method, host, port, path);
    
      @override
      Future<HttpClientRequest> openUrl(String method, Uri url) =>
          _realClient.openUrl(method, url);
    
      @override
      Future<HttpClientRequest> patch(String host, int port, String path) =>
          _realClient.patch(host, port, path);
    
      @override
      Future<HttpClientRequest> patchUrl(Uri url) => _realClient.patchUrl(url);
    
      @override
      Future<HttpClientRequest> post(String host, int port, String path) =>
          _realClient.post(host, port, path);
    
      @override
      Future<HttpClientRequest> postUrl(Uri url) => _realClient.postUrl(url);
    
      @override
      Future<HttpClientRequest> put(String host, int port, String path) =>
          _realClient.put(host, port, path);
    
      @override
      Future<HttpClientRequest> putUrl(Uri url) => _realClient.putUrl(url);
    }
    

    【讨论】:

    • 我发现它很有用,但我仍然觉得有点过于复杂
    • 我也这么认为。
    【解决方案4】:

    这种简单易行的方法对我有用

    var _dio = Dio();
    _dio.options.headers= {"Authorization" : token};
    

    【讨论】:

      【解决方案5】:

      只是扩展了自定义Client 的@Radek Manasek 想法,我将覆盖所有方法,因此您不必再次编写它们。

      import 'dart:convert';
      
      import 'package:http/http.dart' as http;
      import 'package:http/http.dart';
      
      class MyClient extends http.BaseClient {
        final Map<String, String> _defaultHeaders;
        http.Client _httpClient = http.Client();
      
        MyClient(this._defaultHeaders);
      
        @override
        Future<http.StreamedResponse> send(http.BaseRequest request) {
          return _httpClient.send(request);
        }
      
        @override
        Future<Response> get(url, {Map<String, String> headers}) {
          return _httpClient.get(url, headers: _mergedHeaders(headers));
        }
      
        @override
        Future<Response> post(url, {Map<String, String> headers, dynamic body, Encoding encoding}) {
          return _httpClient.post(url, headers: _mergedHeaders(headers), body: body, encoding: encoding);
        }
      
        @override
        Future<Response> patch(url, {Map<String, String> headers, dynamic body, Encoding encoding}) {
          return _httpClient.patch(url, headers: _mergedHeaders(headers), body: body, encoding: encoding);
        }
      
        @override
        Future<Response> put(url, {Map<String, String> headers, dynamic body, Encoding encoding}) {
          return _httpClient.put(url, headers: _mergedHeaders(headers), body: body, encoding: encoding);
        }
      
        @override
        Future<Response> head(url, {Map<String, String> headers}) {
          return _httpClient.head(url, headers: _mergedHeaders(headers));
        }
      
        @override
        Future<Response> delete(url, {Map<String, String> headers}) {
          return _httpClient.delete(url, headers: _mergedHeaders(headers));
        }
      
        Map<String, String> _mergedHeaders(Map<String, String> headers) =>
            {...?_defaultHeaders, ...?headers};
      }
      

      【讨论】:

      • 这如何与全局 HTTP 覆盖一起工作? HttpOverrides.createHttpClient 需要返回一个 HttpClient 而不是 BaseClient。
      猜你喜欢
      • 2022-08-12
      • 2016-06-20
      • 1970-01-01
      • 2013-09-13
      • 1970-01-01
      • 2021-10-07
      • 2017-12-02
      • 2013-05-01
      • 1970-01-01
      相关资源
      最近更新 更多