这个标题在搜索下有很多文章,但还是决定记录下来。也可能是flutter版本升级太快了 导致即使按网上的流程整合还是有很多问题,主要是很多没有写明依赖的包以及版本
1.引用依赖
dio: ^4.0.4
cookie_jar: 3.0.1
dio_cookie_manager: ^2.0.0
shared_preferences: ^2.0.12
2.引入相关的包
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart'; //kDebugMode 使用
import 'package:shared_preferences/shared_preferences.dart';
3.整合的代码
// 封装 dio 请求类
class HttpHelper {
// dio 的 options 配置
static final BaseOptions _options = BaseOptions(
baseUrl: "", // 请求的baseUrl
connectTimeout: 10000, // 连接超时时间
receiveTimeout: 15000, // 响应超时时间
contentType: 'application/x-www-form-urlencoded;charset=utf-8',
);
// get 请求
static get(url, {pathParams, params, needCode = false, cancelToken}) async {
return await request(
url, pathParams, params, 'GET', null, needCode, cancelToken);
}
// post 请求
static post(url, {pathParams, params, needCode = false, cancelToken}) async {
return await request(
url, pathParams, params, 'POST', null, needCode, cancelToken);
}
static request(urlName, pathParams, params, method, header, needCode,
cancelToken) async {
// 处理URL ,通过 urlName 在 urlPath 中匹配相应的 url 路径地址
String url = urlName;
// get请求处理
if (pathParams != null) {
// 处理 https://test_api.com/user/:id/:name => https://test_api.com/user/123/zhangsan 请求连接
pathParams.forEach((key, value) {
if (url.contains(key)) {
url = url.replaceAll(":$key", value.toString());
}
});
} else if (pathParams == null && method == 'GET') {
// 处理 https://test_api.com/user?id=123&name=zhangsan 请求连接
url += '?';
params.forEach((key, value) {
url += '$key=$value&';
});
}
// 读取本地缓存中的数据
dynamic sp = await SharedPreferences.getInstance();
Map headers = {};
// 存储 请求头 参数
if (header != null) {
headers.addAll(header);
}
// 授权信息 Authorization / token
if (sp.get('token') == null && sp.get('Authorization') == null) {
// 处理授权信息不存在的逻辑,即 重新登录 或者 获取授权信息
} else {
// 获取授权信息( token、Authorization 一般出现一个或者两都存在)
if (sp.get('token') != null) {
headers['token'] = sp.get('token');
}
if (sp.get('Authorization') != null) {
headers['Authorization'] = sp.get('Authorization');
}
}
// 设置请求头
_options.headers = Map<String, dynamic>.from(headers);
// 初始化 Dio
Dio _dio = Dio(_options);
// 请求拦击
_dio.interceptors.add(InterceptorsWrapper(onRequest: (request, handler) {
return handler.next(request);
}, onError: (e, handler) async {
if (e.response?.statusCode == 401) {}
}));
late Response response; //late关键字使用 must be assigned before it can be used
// dio 请求处理
try {
response = await _dio.request(url,
data: params,
options: Options(method: method),
cancelToken: cancelToken);
} on DioError catch (e) {
// 请求错误处理 ,错误码 e.response.statusCode
handleHttpError((e.response?.statusCode)!);
if (CancelToken.isCancel(e)) {
if (kDebugMode) {
print('请求取消! ' + e.message);
}
} else {
// 请求发生错误处理
if (e.type == DioErrorType.connectTimeout) {
if (kDebugMode) {
print('连接超时');
}
}
}
}
// 对相应code的处理
if (response == null) {
if (kDebugMode) {
print('响应错误');
}
} else if (needCode) {
// 需要返回code
return response.data;
} else if (!needCode) {
// 不需要返回 code ,统一处理不同 code 的情况
if (response.data != '' && response.data != null) {
// 可对其他不同值的 code 做额外处理
return response.data['data'];
} else {
if (kDebugMode) {
print('其他数据类型处理');
}
return response;
}
}
}
/*
* @description: 处理Http错误码
* @param {type} 错误码
* @return {type}
*/
static handleHttpError(int errorCode) {
if (kDebugMode) {
print('http错误码: $errorCode');
}
}
}
代码中的response变量如果不加上late 会出现以下错误代码
must be assigned before it can be used