在flutter http请求中为所有请求设置默认标头的最佳方法
Posted
技术标签:
【中文标题】在flutter http请求中为所有请求设置默认标头的最佳方法【英文标题】:Best way to set default header for all request in flutter http request 【发布时间】:2019-06-16 16:18:21 【问题描述】:对不起,如果这个问题太简单了,但我是新手,最近找不到在 HTTP 请求中设置默认标头的好方法,我可以扩展类或为其包装一个函数,但不应该有一种内置的简单方法,但我在文档中找不到它。
【问题讨论】:
【参考方案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。以上是关于在flutter http请求中为所有请求设置默认标头的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 上使用 cookie 发出 http 请求?
如何在 react-native 中为 webView 请求设置自定义标头
如何在 Spring Security 中为所有请求添加 jwt 身份验证标头?