如何在Dio拦截器中处理401与403响应状态(含onError场景)
解决Flutter Dio拦截器无法处理401/403状态码的问题
问题根源
Dio默认会将4xx系列状态码(包括401、403)判定为请求错误,这类响应不会进入onResponse回调,而是直接触发onError。你当前把刷新逻辑写在onResponse中,自然无法被执行到。
解决方案
有两种可行的修改方式,根据你的需求选择:
方案1:修改Dio配置,让401/403进入onResponse
在初始化Dio实例时,通过validateStatus参数自定义错误判定规则,让401、403状态码的响应进入onResponse处理:
final dio = Dio(BaseOptions( baseUrl: baseUrl, validateStatus: (status) { // 允许2xx、401、403进入onResponse,其他状态码按错误处理 return status != null && (status >= 200 && status < 300 || status == 401 || status == 403); }, ));
这样你原有的onResponse中的刷新逻辑就能正常触发。
方案2:将刷新逻辑迁移到onError回调
既然Dio默认把4xx丢到onError,直接在该回调中处理认证错误更符合默认行为:
InterceptorsWrapper( onRequest: (options, handler) async { final token = await TokenStorage.getAccessToken(); print("TOKEN SENT -> $token"); if (token != null) { options.headers["Authorization"] = "Bearer $token"; } handler.next(options); }, onError: (DioException error, handler) async { // 仅处理401或403错误 if (error.response?.statusCode == 401 || error.response?.statusCode == 403) { print("REFRESH TRIGGERED"); final refreshToken = await TokenStorage.getRefreshToken(); if (refreshToken == null) { return handler.next(error); } try { // 调用刷新接口,注意_refreshDio需是独立的无拦截器的Dio实例 final refreshResponse = await _refreshDio.post( "$baseUrl/auth/refresh", data: {"refreshToken": refreshToken}, ); final newAccess = refreshResponse.data["accessToken"]; final newRefresh = refreshResponse.data["refreshToken"]; await TokenStorage.saveAccessToken(newAccess); await TokenStorage.saveRefreshToken(newRefresh); // 重新发起原请求 final requestOptions = error.requestOptions; requestOptions.headers["Authorization"] = "Bearer $newAccess"; final retryResponse = await dio.fetch(requestOptions); return handler.resolve(retryResponse); } catch (e) { // 刷新失败,清空令牌并返回原错误 await TokenStorage.clear(); return handler.next(error); } } // 其他错误直接传递 handler.next(error); }, ),
关键注意事项
- 避免循环刷新:
_refreshDio必须是一个独立的Dio实例,不要添加当前的认证拦截器,否则刷新请求若返回401会触发无限循环。 - 防止重复刷新:如果多个请求同时触发401,建议添加一个全局锁(比如用
Completer<bool>或布尔变量),确保同一时间只执行一次刷新逻辑,避免重复调用刷新接口。
内容的提问来源于stack exchange,提问作者Ankit Singh
相关产品推荐
相关产品推荐

