Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как получить ответ сервера в случае ошибки 400 Bad Request при использовании TIdHTTP в Delphi?

Delphi , Интернет и Сети , TCP/IP

 

При работе с HTTP запросами в Delphi, используя компонент TIdHTTP из библиотеки Indy, часто возникает ситуация, когда сервер возвращает ошибку, например, 400 Bad Request. При этом, сервер может передавать полезную информацию об ошибке в теле ответа (например, в формате JSON), которую необходимо получить для дальнейшей обработки. Однако, по умолчанию TIdHTTP генерирует исключение EIdHTTPProtocolException, и прямой доступ к телу ответа становится затруднительным, особенно если кодировка ответа отличается от ожидаемой.

Проблема:

При получении ошибки 400 Bad Request, TIdHTTP выбрасывает исключение EIdHTTPProtocolException. При этом, тело ответа сервера, содержащее полезную информацию, может быть недоступно или искажено из-за проблем с кодировкой. Свойство ErrorMessage исключения может содержать информацию, но национальные символы в ней могут быть потеряны. ssResponse и IdHTTP.Response.ContentStream оказываются пустыми.

Решение 1: Отключение исключения и получение тела ответа

Наиболее эффективным решением является отключение автоматической генерации исключения EIdHTTPProtocolException и явное получение тела ответа. Для этого необходимо настроить свойства HTTPOptions компонента TIdHTTP:

  1. Отключение исключения: Установите флаг hoNoProtocolErrorException в свойстве TIdHTTP.HTTPOptions. Это предотвратит генерацию исключения при получении HTTP-ответа с кодом ошибки.

  2. Получение тела ответа: Установите флаг hoWantProtocolErrorContent в свойстве TIdHTTP.HTTPOptions. Это укажет TIdHTTP сохранять тело ответа даже при ошибке.

После этого, можно проверять код ответа IdHTTP.ResponseCode после выполнения запроса Post и, если он указывает на ошибку (например, 400), читать тело ответа из TStream.

Пример кода:

uses
  IdHTTP, IdGlobal, Classes;

procedure TForm1.Button1Click(Sender: TObject);
var
  IdHTTP: TIdHTTP;
  ssRequest, ssResponse: TStringStream;
  fullUrl: string;
begin
  IdHTTP := TIdHTTP.Create(nil);
  try
    IdHTTP.HTTPOptions := [hoNoProtocolErrorException, hoWantProtocolErrorContent];
    ssRequest := TStringStream.Create('{"key": "value"}', TEncoding.UTF8); // Пример тела запроса
    ssResponse := TStringStream.Create(''); // Создаем пустой стрим для ответа
    fullUrl := 'https://example.com/api/endpoint'; // Замените на ваш URL

    try
      IdHTTP.Post(fullUrl, ssRequest, ssResponse);

      if IdHTTP.ResponseCode = 400 then
      begin
        // Обработка ошибки 400
        ssResponse.Position := 0; // Возвращаемся в начало стрима
        ShowMessage('Ошибка 400: ' + ssResponse.DataString); // Выводим тело ответа
        // Здесь можно распарсить JSON, если ответ в формате JSON
      end
      else
      begin
        // Обработка успешного ответа
        ssResponse.Position := 0;
        ShowMessage('Успех: ' + ssResponse.DataString);
      end;

    except
      on E: Exception do
        ShowMessage('Ошибка: ' + E.Message);
    end;

    finally
      ssRequest.Free;
      ssResponse.Free;
    end;

  finally
    IdHTTP.Free;
  end;
end;

Важно:

  • Убедитесь, что создаете TStringStream с правильной кодировкой (TEncoding.UTF8 в данном примере). Если кодировка ответа сервера отличается, необходимо использовать соответствующую кодировку. Иначе, при чтении DataString данные могут быть искажены.
  • После записи в TStringStream необходимо установить Position в 0, чтобы прочитать данные с начала стрима.

Альтернативное решение (использование перегруженной версии Post):

TIdHTTP имеет перегруженную версию метода Post, которая возвращает строку. Эта версия автоматически учитывает кодировку ответа при преобразовании байтов в строку.

uses
  IdHTTP, IdGlobal;

procedure TForm1.Button1Click(Sender: TObject);
var
  IdHTTP: TIdHTTP;
  ssRequest: TStringStream;
  fullUrl: string;
  responseString: string;
begin
  IdHTTP := TIdHTTP.Create(nil);
  try
    IdHTTP.HTTPOptions := [hoNoProtocolErrorException, hoWantProtocolErrorContent];
    ssRequest := TStringStream.Create('{"key": "value"}', TEncoding.UTF8); // Пример тела запроса
    fullUrl := 'https://example.com/api/endpoint'; // Замените на ваш URL

    try
      responseString := IdHTTP.Post(fullUrl, ssRequest);

      if IdHTTP.ResponseCode = 400 then
      begin
        // Обработка ошибки 400
        ShowMessage('Ошибка 400: ' + responseString); // Выводим тело ответа
        // Здесь можно распарсить JSON, если ответ в формате JSON
      end
      else
      begin
        // Обработка успешного ответа
        ShowMessage('Успех: ' + responseString);
      end;

    except
      on E: Exception do
        ShowMessage('Ошибка: ' + E.Message);
    end;

    finally
      ssRequest.Free;
    end;

  finally
    IdHTTP.Free;
  end;
end;

В этом случае, вам не нужно создавать TStringStream для ответа, так как результат возвращается в виде строки. TIdHTTP самостоятельно определяет кодировку ответа и преобразует байты в строку корректно.

В заключение:

Оба представленных решения позволяют получить тело ответа сервера при возникновении ошибки 400 Bad Request. Выбор конкретного решения зависит от ваших предпочтений и требований к коду. Важно помнить о правильной обработке кодировок, чтобы избежать искажения данных. Использование перегруженной версии Post, возвращающей строку, может упростить код и избежать проблем с кодировкой, но требует включения hoNoProtocolErrorException и hoWantProtocolErrorContent.

Создано по материалам из источника по ссылке.

Статья описывает методы получения полного ответа сервера, включая тело ответа, при возникновении ошибки 400 Bad Request при использовании TIdHTTP в Delphi, с акцентом на обработку кодировок.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: TCP/IP ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-21 07:24:51/0.0039680004119873/0