在 flutter 中收到完整标头之前连接已关闭 http post

发布于 2025-01-11 23:36:14 字数 1017 浏览 0 评论 0原文

我在尝试使用我的 API 时遇到问题,在跟进这个问题后,我陷入了困境,并且我尝试了不同版本的不同模拟器,但问题仍然存在。

错误:

DioError [DioErrorType.other]: HttpException: Connection closed before full header was received, uri = http://10.0.2.2:7108/Users/authenticate

Flutter doctor

在此处输入图像描述

Http Post

class AuthenticateRemoteApi extends AuthenticateGateway {
  final AuthenticateMapper _authenticateMapper = AuthenticateMapper();

  @override
  Future<SesionUser> login(Authenticate user) async {
    var dio = Dio();
    dio.options.headers['content-Type'] = 'application/json';
    String url = 'http://10.0.2.2:7108/Users/authenticate';

    try {
      Response response = await dio.post(url, data: authenticateModelToJson(user));
      return _authenticateMapper.fromMap(jsonDecode(response.data));
    } catch (e) {
      throw Exception(e);
    }
  }
}

I'm having problems trying to consume my API, and after following up on this problem I'm stuck in the matter and I've tried different emulators in various versions and the problem persists.

Error:

DioError [DioErrorType.other]: HttpException: Connection closed before full header was received, uri = http://10.0.2.2:7108/Users/authenticate

Flutter doctor

enter image description here

Http Post

class AuthenticateRemoteApi extends AuthenticateGateway {
  final AuthenticateMapper _authenticateMapper = AuthenticateMapper();

  @override
  Future<SesionUser> login(Authenticate user) async {
    var dio = Dio();
    dio.options.headers['content-Type'] = 'application/json';
    String url = 'http://10.0.2.2:7108/Users/authenticate';

    try {
      Response response = await dio.post(url, data: authenticateModelToJson(user));
      return _authenticateMapper.fromMap(jsonDecode(response.data));
    } catch (e) {
      throw Exception(e);
    }
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

顾北清歌寒 2025-01-18 23:36:14

我通过创建这个拦截器来解决这个问题。

它的想法是当遇到这个随机错误时只是重试请求。

/// Interceptor
class RetryOnConnectionChangeInterceptor extends Interceptor {
  final Dio dio;

  RetryOnConnectionChangeInterceptor({
    required this.dio,
  });

  @override
  void onError(DioError err, ErrorInterceptorHandler handler) async {
  if (_shouldRetryOnHttpException(err)) {
      try {
        handler.resolve(await DioHttpRequestRetrier(dio: dio).requestRetry(err.requestOptions).catchError((e) {
          handler.next(err);
        }));
      } catch (e) {
        handler.next(err);
      }
    } else {
      handler.next(err);
    }

  }

  bool _shouldRetryOnHttpException(DioError err) {
    return err.type == DioErrorType.other &&
        ((err.error is HttpException && err.message.contains('Connection closed before full header was received')));
  }
}

/// Retrier
class DioHttpRequestRetrier {
  final Dio dio;

  DioHttpRequestRetrier({
    required this.dio,
  });

  Future<Response> requestRetry(RequestOptions requestOptions) async {
    return dio.request(
      requestOptions.path,
      cancelToken: requestOptions.cancelToken,
      data: requestOptions.data,
      onReceiveProgress: requestOptions.onReceiveProgress,
      onSendProgress: requestOptions.onSendProgress,
      queryParameters: requestOptions.queryParameters,
      options: Options(
        contentType: requestOptions.contentType,
        headers: requestOptions.headers,
        sendTimeout: requestOptions.sendTimeout,
        receiveTimeout: requestOptions.receiveTimeout,
        extra: requestOptions.extra,
        followRedirects: requestOptions.followRedirects,
        listFormat: requestOptions.listFormat,
        maxRedirects: requestOptions.maxRedirects,
        method: requestOptions.method,
        receiveDataWhenStatusError: requestOptions.receiveDataWhenStatusError,
        requestEncoder: requestOptions.requestEncoder,
        responseDecoder: requestOptions.responseDecoder,
        responseType: requestOptions.responseType,
        validateStatus: requestOptions.validateStatus,
      ),
    );
  }
}

用法:将此拦截器 [RetryOnConnectionChangeInterceptor] 添加到您的 Dio 客户端实例

I have came with this work around by creating this interceptor.

The idea of it is when encountering this random error just to retry the request.

/// Interceptor
class RetryOnConnectionChangeInterceptor extends Interceptor {
  final Dio dio;

  RetryOnConnectionChangeInterceptor({
    required this.dio,
  });

  @override
  void onError(DioError err, ErrorInterceptorHandler handler) async {
  if (_shouldRetryOnHttpException(err)) {
      try {
        handler.resolve(await DioHttpRequestRetrier(dio: dio).requestRetry(err.requestOptions).catchError((e) {
          handler.next(err);
        }));
      } catch (e) {
        handler.next(err);
      }
    } else {
      handler.next(err);
    }

  }

  bool _shouldRetryOnHttpException(DioError err) {
    return err.type == DioErrorType.other &&
        ((err.error is HttpException && err.message.contains('Connection closed before full header was received')));
  }
}

/// Retrier
class DioHttpRequestRetrier {
  final Dio dio;

  DioHttpRequestRetrier({
    required this.dio,
  });

  Future<Response> requestRetry(RequestOptions requestOptions) async {
    return dio.request(
      requestOptions.path,
      cancelToken: requestOptions.cancelToken,
      data: requestOptions.data,
      onReceiveProgress: requestOptions.onReceiveProgress,
      onSendProgress: requestOptions.onSendProgress,
      queryParameters: requestOptions.queryParameters,
      options: Options(
        contentType: requestOptions.contentType,
        headers: requestOptions.headers,
        sendTimeout: requestOptions.sendTimeout,
        receiveTimeout: requestOptions.receiveTimeout,
        extra: requestOptions.extra,
        followRedirects: requestOptions.followRedirects,
        listFormat: requestOptions.listFormat,
        maxRedirects: requestOptions.maxRedirects,
        method: requestOptions.method,
        receiveDataWhenStatusError: requestOptions.receiveDataWhenStatusError,
        requestEncoder: requestOptions.requestEncoder,
        responseDecoder: requestOptions.responseDecoder,
        responseType: requestOptions.responseType,
        validateStatus: requestOptions.validateStatus,
      ),
    );
  }
}

Usage: add this interceptor [RetryOnConnectionChangeInterceptor] to your Dio client instance

浅语花开 2025-01-18 23:36:14

我认为这可能是一个包错误,通常在用户没有互联网连接时出现。已在 #1269#377 来自软件包存储库的问题。我建议您使用另一个包。

I think this could be a package bug, usually appears when the user doesn't has internet connect. Reported in #1269 and #377 issue from the package repository. I recommend you to use another package.

妳是的陽光 2025-01-18 23:36:14

就我而言,当我在模拟器上构建应用程序时,总是会发生此错误,很少出现在真实设备上。如果您使用的是 Android Studio,请尝试使用 Pixel 6 API 33。

In my case this error always occurs when I build app on emulator, rarely appears on real device. If you are using Android Studio, try with Pixel 6 API 33.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文