在flutter http请求中为所有请求设置默认头的最佳方法

kpbpu008  于 2023-05-19  发布在  Flutter
关注(0)|答案(7)|浏览(258)

抱歉,如果这个问题如此基本,但我是新的flutter和最近找不到一个好的方法来设置一个默认的头在HTTP请求我可以扩展类或 Package 一个函数到它,但不应该有一个简单的方法是内置的,但我找不到它在文档中。

avkwfej4

avkwfej41#

这可以很容易地与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());

有关详细信息,请参阅文档。

sqougxex

sqougxex2#

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);
  }
}
cvxl0en2

cvxl0en23#

注册自定义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(...)添加自定义头。您需要将其扩展到所有其他方法,如headheadUrlopenpost,...

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);
}
ac1kyiln

ac1kyiln4#

这个简单易行的方法对我很有效

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

1qczuiv05#

只是扩展@Radek Manasek自定义Client的想法,我覆盖了所有的方法,这样你就不必再编写它们了。

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};
}
ndh0cuux

ndh0cuux6#

我正在创建一个单例类,并在其中初始化dio,并在所有需要进行http请求的控制器中使用它。
有两种方法可以在dio客户端中添加头文件

_dio.interceptors.addAll([
      InterceptorsWrapper(
        onRequest: (options, handler) {
          options.headers.addAll({'authorization': 'Bearer $_authToken'});
          handler.next(options);
        },
      ),
      CustomInterceptors(), // your other interceptors
    ]);

第二个是这样的

void setAuthToken(String token) {
    _authToken = token;
    _dio.options.headers['authorization'] = 'Bearer $token';
  }

第一个方法会在发出每个请求之前添加头文件,所以我们可以根据业务逻辑添加条件文件。所以第一种方法比第二种方法好得多。

flseospp

flseospp7#

扩展@Radek和@vovahost只是使它们的实现适用于库更新,并添加了检查状态代码和在某些响应中抛出错误的功能。

import 'dart:async';
import 'dart:convert';

import 'package:http/http.dart';
import 'package:http/http.dart' as http;

class BaseNetworkClient extends http.BaseClient {
  Map<String, String> _defaultHeaders = {
    'Content-Type': 'application/json',
  };

  final http.Client _httpClient = http.Client();

  addTokenToHeader(String token) {
    _mergedHeaders({"auth_token": token});
  }

  Map<String, String> _mergedHeaders(Map<String, String> headers) =>
      {...?_defaultHeaders, ...?headers};

  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) {
    return _httpClient.send(request).then((response) async {
      _checkError( await http.Response.fromStream(response));

      return response;
    });
  }

  @override
  Future<Response> get(url, {Map<String, String>? headers}) {
    return _httpClient
        .get(url,
            headers:
                headers != null ? _mergedHeaders(headers) : _defaultHeaders)
        .then(_checkError);
  }

  @override
  Future<Response> post(url,
      {Map<String, String>? headers, dynamic body, Encoding? encoding}) {
    return _httpClient
        .post(url,
            headers:
                headers != null ? _mergedHeaders(headers) : _defaultHeaders,
            body: body,
            encoding: encoding)
        .then(_checkError);
  }

  @override
  Future<Response> patch(url,
      {Map<String, String>? headers, dynamic body, Encoding? encoding}) {
    return _httpClient
        .patch(url,
            headers:
                headers != null ? _mergedHeaders(headers) : _defaultHeaders,
            body: body,
            encoding: encoding)
        .then(_checkError);
  }

  @override
  Future<Response> put(url,
      {Map<String, String>? headers, dynamic body, Encoding? encoding}) {
    return _httpClient
        .put(url,
            headers:
                headers != null ? _mergedHeaders(headers) : _defaultHeaders,
            body: body,
            encoding: encoding)
        .then(_checkError);
  }

  @override
  Future<Response> head(url, {Map<String, String>? headers}) {
    return _httpClient
        .head(url,
            headers:
                headers != null ? _mergedHeaders(headers) : _defaultHeaders)
        .then(_checkError);
  }

  @override
  Future<Response> delete(url,
      {Map<String, String>? headers, Object? body, Encoding? encoding}) {
    return _httpClient
        .delete(url,
            headers:
                headers != null ? _mergedHeaders(headers) : _defaultHeaders)
        .then(_checkError);
  }

  Response _checkError(Response response) {
    final int? statusCode = response.statusCode;

    if (statusCode == null) {
    throw  //Todoo: add custom exception don't expect response.body
      
    
    } else if (statusCode < 200 || statusCode > 400) {
      throw  //Todoo: add custom exception 
    }
    return response;
  }
}

相关问题