错误:错误状态:FormData 已为 Dio 拦截器最终确定

问题描述 投票:0回答:1

我正在使用 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 实例,但我已经尝试了所有我能做的,但没有结果,而且我还尝试在发出请求之前检查令牌是否过期,但仍然没有给我一个更好的结果。

我能做什么?

flutter interceptor dio
1个回答
0
投票

您需要为每个请求创建一个新的“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;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.