尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
网络拦截器 - 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请求。
RELATED

相关推荐

Python的数据存储与运算符

Python的数据存储与运算符

大家好,最近在系统学习 Python 基础,把核心知识点整理成这份笔记,分享给正在入门 Python 的朋友们。零基础学编程,基础概念一定要吃透,下面跟着我的笔记一起梳理重点!1. 变量定义格式Python 定义变量语法十…

📅 2026/9/8 5:57:07
英灵神殿挂?用“神器”白嫖私人服务器,告别卡顿

英灵神殿挂?用“神器”白嫖私人服务器,告别卡顿

还在为《英灵神殿》官方服务器的高延迟和“英灵神殿挂”(指利用网络延迟或外挂破坏游戏体验)而烦恼吗?与其在拥挤的官方服里和“神仙”斗智斗勇,不如自己白嫖一个专属的私人服务器,只邀请信得过的朋友加入,…

📅 2026/9/10 11:10:05
VS Code 与 Flutter:高效移动开发的完美组合

VS Code 与 Flutter:高效移动开发的完美组合

1. 引言 在 Flutter 移动开发领域,选择一个合适的集成开发环境(IDE)至关重要。Visual Studio Code(简称 VS Code)凭借其轻量、高效和强大的扩展生态,已成为众多 Flutter 开发者的首选工具。本文将详细介绍…

📅 2026/9/20 12:34:30
MORE NEWS

更多资讯

📰

订阅号升级服务号:3个核心考点拆解,新手避坑指南

订阅号升级服务号:3个核心考点拆解,新手避坑指南 面试被问“订阅号怎么升级服务号”却答不上来?这不仅仅是个业务问题,更是考察你对微信开放平台底层逻辑、接口权限模型以及后端状态机设计理解的试金石。很多新手在准备面试时,往往只盯着高并发、分布式…

📰

3个坑避开进击的巨人巨人的真相面试挂科风险

3个坑避开进击的巨人巨人的真相面试挂科风险 复制来的代码跑不通不知道怎么调?别慌。在 实战项目 里,这种“水土不服”比单纯语法错误更让人崩溃。很多人对着屏幕发呆,明明逻辑看着没错,一执行就报红,这时候如果没人指点,心态很容易崩。其实,90%…

📰

搞定 DS1302 时钟芯片:3 招解决嵌入式高频面试题报错难题

搞定 DS1302 时钟芯片:3 招解决嵌入式高频面试题报错难题 面试被问 DS1302 寄存器配置,脑子里一片浆糊?调试时 I2C 或 SPI 通讯报错一堆看不懂…

📰

动物农庄源码拆解:版本升级API全变?这份保姆级教程救你

动物农庄源码拆解:版本升级API全变?这份保姆级教程救你 版本升级后 API 全变了,老代码直接报错,调试到深夜才发现是参数结构彻底重构。很多开发者在接手旧项目或升级依赖时,都会遇到这种“断崖式”的接口变更,导致业务逻辑瘫痪。这时候,光看官…

📰

5分钟吃透精炼石中盐源码解析:避开3大坑

5分钟吃透精炼石中盐源码解析:避开3大坑 官方文档那一堆术语看得头大?别慌。 很多老手都在 CSDN 上吐槽过,看官方 API 文档像看天书,抓不住重点。 其实核心逻辑就那几行代码,咱们直接上源码解析。 考点梳理:面试官到底在问什么…

📰

范文同面试必考5题:配置不卡死,最佳实践全解析

范文同面试必考5题:配置不卡死,最佳实践全解析 配置环境卡半天,代码跑不通,这是很多开发者刚接触范文同时的噩梦。别急,今天拆解5个高频面试题,直击最佳实践,让你面试不慌。 考点梳理:范文同到底考什么…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬