错误:错误状态:FormData 已完成。这通常意味着您在重复的请求中使用相同的 FormData

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

我正在尝试将图像上传到服务器,但是当它发出请求时,它在获取令牌后调用拦截器来刷新令牌,它将抛出此错误:

[错误:flutter/runtime/dart_vm_initializer.cc(41)] 未处理的异常:DioException [未知]:null E/flutter(5915):错误:错误状态:FormData 已完成。这通常意味着您在重复的请求中使用相同的 FormData。

这是代码:

final token = storageService.getAccessToken();
String fileName = photo.path.split('/').last;
Map<String, String> headers = <String, String>{
  'Accept': 'application/json',
  'content-type': 'multipart/form-data',
  'Authorization': token!,
};

final formData = dios.FormData.fromMap({
  "image": await dios.MultipartFile.fromFile(
    photo.path,
    filename: fileName,
  ),
});
final response = await dio.patch(
  "${AppConfig.endPoint}api/upload-picture",
  data: formData,
  options: dios.Options(
    headers: headers,
  ),
);

if (response.statusCode == 200) {
  return true;
} else if (response.data['code'] == 'token_not_valid') {
  final anotherformData = dios.FormData.fromMap({
    "profile_picture": await dios.MultipartFile.fromFile(
      photo.path,
      filename: fileName,
    ),
  });
  await dio.patch(
    "${AppConfig.endPoint}api/upload-picture",
    data: anotherformData,
    options: dios.Options(
      headers: headers,
    ),
  );
} else {
  throw Exception(response.statusMessage);
}
getUserProfile();
return true;}

拦截器包装器

dio.interceptors.addAll([
  PrettyDioLogger(
      requestHeader: true,
      requestBody: true,
      responseBody: true,
      responseHeader: false,
      error: true,
      compact: true,
      request: true,
      maxWidth: 150),

  dios.InterceptorsWrapper(
    onError: (dios.DioException e, handler) async {
      if (e.response?.data['code'] == 'token_not_valid') {
        // If a 401 response is received, refresh the access token
        RefreshTokenResponse? newAccessToken = await refreshToken(
            RefreshTokenBody(
                refresh: storageService.getRefreshToken() ?? ''));

        //Save the  new token and refresh token here
        storageService.setAccessToken(newAccessToken?.access ?? '');

        // Update the request header with the new access token
        e.requestOptions.headers['Authorization'] =
            'Bearer ${newAccessToken?.access}';

        // Repeat the request with the updated header
        return handler.resolve(await dio.fetch(e.requestOptions));
      }
      return handler.next(e);
    },
  ),
]);

请告诉我如何解决这个问题。谢谢你。

flutter dart interceptor dio
1个回答
0
投票

您尝试为多个请求重用同一个 FormData 对象。 Dio 中的 FormData 对象被设计用于单个 HTTP 请求,并且在最终确定后无法修改或重用。

您应该为每个 HTTP 请求创建一个新的 FormData 对象。在您的代码中,您尝试对初始请求重用相同的 FormData 对象 formData,对后续请求重用另一个 formData,这会导致错误。

final token = storageService.getAccessToken();
    String fileName = photo.path.split('/').last;
    Map<String, String> headers = <String, String>{
      'Accept': 'application/json',
      'content-type': 'multipart/form-data',
      'Authorization': token!,
    };
    
    final formData = dios.FormData.fromMap({
      "image": await dios.MultipartFile.fromFile(
        photo.path,
        filename: fileName,
      ),
    });
    final response = await dio.patch(
      "${AppConfig.endPoint}api/upload-picture",
      data: formData,
      options: dios.Options(
        headers: headers,
      ),
    );
    
    if (response.statusCode == 200) {
      return true;
    } else if (response.data['code'] == 'token_not_valid') {
      final anotherFormData = dios.FormData.fromMap({
        "profile_picture": await dios.MultipartFile.fromFile(
          photo.path,
          filename: fileName,
        ),
      });
      await dio.patch(
        "${AppConfig.endPoint}api/upload-picture",
        data: anotherFormData,
        options: dios.Options(
          headers: headers,
        ),
      );
    } else {
      throw Exception(response.statusMessage);
    }
    getUserProfile();
    return true;
© www.soinside.com 2019 - 2024. All rights reserved.