网络拦截器 - Flutter在鸿蒙平台处理HTTP请求

发布时间:2026/7/23 2:18:26
网络拦截器 - Flutter在鸿蒙平台处理HTTP请求 概述在Flutter应用开发中网络请求是不可或缺的一部分。为了统一处理HTTP请求的认证、日志、错误处理等逻辑使用拦截器是一个很好的实践。Dio库提供了强大的拦截器机制可以在请求发送前、响应返回后、错误发生时进行统一处理。本文将详细介绍网络拦截器的核心概念、使用方法、高级特性以及在鸿蒙平台上的实现细节。核心概念什么是网络拦截器网络拦截器是一种中间件机制允许在HTTP请求的各个阶段插入自定义逻辑阶段拦截器类型作用请求发送前请求拦截器添加认证信息、日志记录、参数加密响应返回后响应拦截器数据解析、日志记录、错误处理错误发生时错误拦截器错误重试、错误转换、错误上报拦截器的优势代码复用将通用逻辑抽离到拦截器中统一处理集中处理认证、日志、错误等逻辑易于维护修改逻辑只需改动拦截器解耦合业务代码与网络层解耦拦截器链多个拦截器可以组成一个拦截器链按照顺序执行请求 → 拦截器1 → 拦截器2 → ... → 服务器 响应 → 拦截器n → 拦截器n-1 → ... → 业务代码基本使用安装依赖dependencies:dio:^5.4.0创建请求拦截器importpackage:dio/dio.dart;classAuthInterceptorextendsInterceptor{overridevoidonRequest(RequestOptionsoptions,RequestInterceptorHandlerhandler){options.headers[Authorization]Bearer token;super.onRequest(options,handler);}}创建响应拦截器classLoggingInterceptorextendsInterceptor{overridevoidonResponse(Responseresponse,ResponseInterceptorHandlerhandler){print(RESPONSE:${response.data});super.onResponse(response,handler);}}添加拦截器到DiofinaldioDio();dio.interceptors.add(AuthInterceptor());dio.interceptors.add(LoggingInterceptor());核心代码示例代码示例1认证拦截器importpackage:dio/dio.dart;importpackage:shared_preferences/shared_preferences.dart;classAuthInterceptorextendsInterceptor{overridevoidonRequest(RequestOptionsoptions,RequestInterceptorHandlerhandler)async{finalprefsawaitSharedPreferences.getInstance();finaltokenprefs.getString(access_token);if(token!null){options.headers[Authorization]Bearer$token;}options.headers[Content-Type]application/json;super.onRequest(options,handler);}overridevoidonResponse(Responseresponse,ResponseInterceptorHandlerhandler){if(response.statusCode401){}super.onResponse(response,handler);}overridevoidonError(DioExceptionerr,ErrorInterceptorHandlerhandler){if(err.response?.statusCode401){}super.onError(err,handler);}}代码说明请求拦截在请求发送前添加认证token和Content-Type响应拦截处理401状态码token过期错误拦截处理请求错误时的401状态码异步操作使用SharedPreferences获取token代码示例2日志拦截器classLoggingInterceptorextendsInterceptor{overridevoidonRequest(RequestOptionsoptions,RequestInterceptorHandlerhandler){print(REQUEST[${options.method}] PATH:${options.path});print(HEADERS:${options.headers});if(options.data!null){print(BODY:${options.data});}super.onRequest(options,handler);}overridevoidonResponse(Responseresponse,ResponseInterceptorHandlerhandler){print(RESPONSE[${response.statusCode}] PATH:${response.requestOptions.path});print(DATA:${response.data});super.onResponse(response,handler);}overridevoidonError(DioExceptionerr,ErrorInterceptorHandlerhandler){print(ERROR[${err.response?.statusCode}] PATH:${err.requestOptions.path});print(ERROR:$err);super.onError(err,handler);}}代码说明请求日志记录请求方法、路径、头信息和请求体响应日志记录响应状态码、路径和响应数据错误日志记录错误状态码、路径和错误信息调试方便帮助开发者调试网络请求代码示例3API客户端封装importpackage:dio/dio.dart;classApiClient{staticlateDio_dio;staticvoidinit(){_dioDio(BaseOptions(baseUrl:https://api.example.com,connectTimeout:constDuration(seconds:10),receiveTimeout:constDuration(seconds:10),));_dio.interceptors.add(AuthInterceptor());_dio.interceptors.add(LoggingInterceptor());_dio.interceptors.add(RetryInterceptor(dio:_dio,options:constRetryOptions(retries:3,retryInterval:Duration(seconds:1),retryEvaluator:_defaultRetryEvaluator,),));}staticbool_defaultRetryEvaluator(DioExceptionerror){returnerror.typeDioExceptionType.connectionTimeout||error.typeDioExceptionType.receiveTimeout||error.typeDioExceptionType.sendTimeout;}staticDiogetinstance_dio;staticFutureResponseget(Stringpath,{MapString,dynamic?queryParameters})async{returnawait_dio.get(path,queryParameters:queryParameters);}staticFutureResponsepost(Stringpath,{dynamicdata})async{returnawait_dio.post(path,data:data);}staticFutureResponseput(Stringpath,{dynamicdata})async{returnawait_dio.put(path,data:data);}staticFutureResponsedelete(Stringpath)async{returnawait_dio.delete(path);}}代码说明单例模式使用静态实例避免重复创建基础配置设置baseUrl、超时时间拦截器链添加认证、日志、重试拦截器请求方法封装GET、POST、PUT、DELETE方法重试逻辑对超时错误自动重试3次代码示例4错误处理拦截器classErrorInterceptorextendsInterceptor{overridevoidonError(DioExceptionerr,ErrorInterceptorHandlerhandler){finalerrorMessage_getErrorMessage(err);print(Error:$errorMessage);finalcustomErrorApiError(code:err.response?.statusCode??-1,message:errorMessage,originalError:err,);handler.reject(DioException(requestOptions:err.requestOptions,error:customError,type:err.type,response:err.response,));}String_getErrorMessage(DioExceptionerr){switch(err.type){caseDioExceptionType.connectionTimeout:return连接超时;caseDioExceptionType.sendTimeout:return发送超时;caseDioExceptionType.receiveTimeout:return接收超时;caseDioExceptionType.badResponse:return服务器错误${err.response?.statusCode};caseDioExceptionType.cancel:return请求已取消;caseDioExceptionType.connectionError:return网络连接错误;default:return未知错误;}}}classApiError{finalint code;finalStringmessage;finalDioExceptionoriginalError;ApiError({requiredthis.code,requiredthis.message,requiredthis.originalError,});}代码说明错误转换将DioException转换为自定义ApiError错误消息根据错误类型提供友好的错误消息错误信息保存原始错误信息便于调试错误码提取HTTP状态码高级特性1. 请求重试dio.interceptors.add(RetryInterceptor(dio:dio,options:constRetryOptions(retries:3,retryInterval:Duration(seconds:1),retryEvaluator:(error)error.typeDioExceptionType.connectionTimeout,),));2. 请求缓存classCacheInterceptorextendsInterceptor{finalMapString,Response_cache{};overridevoidonRequest(RequestOptionsoptions,RequestInterceptorHandlerhandler){if(options.methodGET){finalcachedResponse_cache[options.path];if(cachedResponse!null){handler.resolve(cachedResponse);return;}}handler.next(options);}overridevoidonResponse(Responseresponse,ResponseInterceptorHandlerhandler){if(response.requestOptions.methodGET){_cache[response.requestOptions.path]response;}handler.next(response);}}3. 请求限流classRateLimitInterceptorextendsInterceptor{int _requestCount0;DateTime?_lastResetTime;overridevoidonRequest(RequestOptionsoptions,RequestInterceptorHandlerhandler){finalnowDateTime.now();if(_lastResetTimenull||now.difference(_lastResetTime!)constDuration(seconds:1)){_requestCount0;_lastResetTimenow;}if(_requestCount10){handler.reject(DioException(requestOptions:options,error:Rate limit exceeded,));}else{_requestCount;handler.next(options);}}}4. 参数加密classEncryptionInterceptorextendsInterceptor{overridevoidonRequest(RequestOptionsoptions,RequestInterceptorHandlerhandler){if(options.data!null){options.data_encrypt(options.data);}handler.next(options);}dynamic_encrypt(dynamicdata){returndata;}}在鸿蒙平台的实现鸿蒙平台适配鸿蒙平台对Flutter网络请求的支持与Android类似因为鸿蒙兼容Android应用。需要注意以下几点网络权限需要在module.json5中声明网络权限HTTPS支持鸿蒙平台支持HTTPS请求网络代理可以配置网络代理进行调试鸿蒙平台权限配置在module.json5中配置网络权限{module:{requestPermissions:[{name:ohos.permission.INTERNET,reason:需要网络权限发送HTTP请求,usedScene:{ability:[{name:MainAbility,when:inuse}],permissionFlags:[grantMode:system_grant]}}]}}鸿蒙平台注意事项网络安全鸿蒙平台要求使用HTTPS连接证书验证需要正确配置SSL证书代理配置调试时可以配置网络代理性能对比操作无拦截器有拦截器请求时间正常略有增加毫秒级代码复杂度高重复逻辑低统一处理可维护性差好最佳实践1. 封装API客户端将所有网络请求封装在API客户端中classApiClient{staticFutureUsergetUser(int id)async{finalresponseawait_dio.get(/users/$id);returnUser.fromJson(response.data);}staticFutureListUsergetUsers()async{finalresponseawait_dio.get(/users);return(response.dataasList).map((e)User.fromJson(e)).toList();}}2. 统一错误处理在错误拦截器中统一处理错误classErrorInterceptorextendsInterceptor{overridevoidonError(DioExceptionerr,ErrorInterceptorHandlerhandler){finalerror_handleError(err);handler.reject(error);}DioException_handleError(DioExceptionerr){// 统一错误处理逻辑returnerr;}}3. 合理使用拦截器根据需求选择合适的拦截器dio.interceptors.add(AuthInterceptor());dio.interceptors.add(LoggingInterceptor());dio.interceptors.add(ErrorInterceptor());4. 避免重复拦截不要在多个地方添加相同的拦截器// 错误示例dio.interceptors.add(AuthInterceptor());dio.interceptors.add(AuthInterceptor());// 重复添加5. 测试拦截器编写测试用例验证拦截器功能voidmain(){test(AuthInterceptor adds token,()async{finaldioDio();dio.interceptors.add(AuthInterceptor());// 测试拦截器是否正确添加token});}常见问题Q1: 拦截器不生效怎么办A检查以下几点是否正确添加了拦截器到Dio实例拦截器的顺序是否正确是否调用了handler.next()或handler.resolve()Q2: 如何在拦截器中获取上下文A可以通过RequestOptions的extra参数传递上下文dio.get(/users,options:Options(extra:{context:context}));Q3: 拦截器可以异步操作吗A可以请求拦截器支持异步操作overridevoidonRequest(RequestOptionsoptions,RequestInterceptorHandlerhandler)async{finaltokenawaitgetToken();options.headers[Authorization]token;handler.next(options);}Q4: 如何取消请求A使用CancelToken取消请求finalcancelTokenCancelToken();dio.get(/users,cancelToken:cancelToken);cancelToken.cancel(Request cancelled);Q5: 如何处理HTTPS证书问题A可以通过配置Dio的HttpClientAdapter来处理dio.httpClientAdapterHttp2Adapter(ConnectionManager(idleTimeout:constDuration(seconds:10),),);总结网络拦截器是Flutter应用中处理HTTP请求的重要机制通过Dio库的拦截器可以实现认证、日志、错误处理等统一逻辑。在鸿蒙平台上网络拦截器的实现与Android类似但需要注意网络权限和HTTPS配置。选择合适的拦截器需要根据应用需求来决定拦截器适用场景特点认证拦截器需要登录的应用自动添加认证信息日志拦截器开发调试记录请求和响应信息错误拦截器所有应用统一错误处理重试拦截器不稳定网络自动重试失败请求希望本文能帮助你更好地理解和使用网络拦截器在Flutter应用中处理HTTP请求。