我正在使用 Dio Interceptor 作为 RefreshToken。但是,每当我向后端发出请求并且令牌已经过期而我在请求中使用 FormData 时,它就会返回错误:“错误:错误状态:由于 Dio 的重试机制,FormData 已经最终确定重新生成有效令牌后使用。”
H
MyApiProvider() {
_dio.interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) async {
options.headers["Accept"] = "application";
String? token = _getStorage.read("accessToken");
options.headers["Authorization"] = 'Bearer $token';
return handler.next(options);
},
onError: (error, handler) async {
if (error.response?.statusCode == 401) {
final newAccessToken = await refreshToken();
if (newAccessToken != null) {
_dio.options.headers["Authorization"] = 'Bearer $newAccessToken';
return handler.resolve(await _dio.fetch(error.requestOptions));
}
}
return handler.next(error);
},
));
}
这里还有请求功能代码。
Future<void> uploadMultipleImages({
required dio.FormData formData,
required List<String> imagePaths,
required Map<String, dynamic> bodyData,
required Function(List<String>) onUploadComplete,
required String endpoint,
}) async {
if (imagePaths.isEmpty) {
return;
}
try {
for (int i = 0; i < imagePaths.length; i++) {
File file = File(imagePaths[i]);
String fileName = file.path.split('/').last;
// Add file to FormData
formData.files.add(MapEntry(
'multiple_images',
await dio.MultipartFile.fromFile(
file.path,
filename: fileName,
),
));
// Add additional data to FormData
bodyData.forEach((key, value) {
formData.fields.add(MapEntry(key, value.toString()));
});
final response = await _dio.post(
endpoint,
data: formData,
options: dio.Options(
contentType: dio.Headers.formUrlEncodedContentType,
),
);
final message = response.data["message"].toString();
_getStorage.writeIfNull('vIsApproved', false);
SnackBarUtils.showSnackBar("Success", message);
}
} on DioException catch (error) {
throw DioErrors.mapDioExceptionToHttpError(error);
} catch (e) {
print(e);
rethrow;
}
}
我也做了一些研究,我知道它需要新的 formData 实例,但我已经尝试了所有我能做的,但没有结果,而且我还尝试在发出请求之前检查令牌是否过期,但仍然没有给我一个更好的结果。
我能做什么?
您需要为每个请求创建一个新的“formdata”实例..
Future<void> uploadMultipleImages({
required List<String> imagePaths,
required Map<String, dynamic> bodyData,
required Function(List<String>) onUploadComplete,
required String endpoint,
}) async {
if (imagePaths.isEmpty) {
return;
}
try {
for (int i = 0; i < imagePaths.length; i++) {
File file = File(imagePaths[i]);
String fileName = file.path.split('/').last;
FormData formData = FormData();
formData.files.add(MapEntry(
'multiple_images',
await MultipartFile.fromFile(
file.path,
filename: fileName,
),
));
bodyData.forEach((key, value) {
formData.fields.add(MapEntry(key, value.toString()));
});
final response = await _dio.post(
endpoint,
data: formData,
options: Options(
contentType: Headers.formUrlEncodedContentType,
),
);
final message = response.data["message"].toString();
_getStorage.writeIfNull('vIsApproved', false);
SnackBarUtils.showSnackBar("Success", message);
}
} on DioError catch (error) {
if (error.response?.statusCode == 401) {
// Handle token expiration
final newAccessToken = await refreshToken();
if (newAccessToken != null) {
_dio.options.headers["Authorization"] = 'Bearer $newAccessToken';
await uploadMultipleImages(
imagePaths: imagePaths,
bodyData: bodyData,
onUploadComplete: onUploadComplete,
endpoint: endpoint,
);
return;
}
}
throw DioErrors.mapDioExceptionToHttpError(error);
} catch (e) {
print(e);
rethrow;
}
}