Как перевести код HTTP-запроса с авторизацией из 1С 8.3 в Delphi 6?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции различных систем автоматизации с внешним оборудованием (например, с IP-телефонами, шлюзами или сторонними веб-сервисами) разработчики часто сталкиваются с необходимостью миграции готовых решений между разными средами разработки. В этой статье мы подробно рассмотрим, как перевести рабочий код отправки HTTP-запроса с авторизацией из современной платформы 1С 8.3 в проверенную временем среду Delphi 6.

Перенос кода из современной объектной модели 1С в Delphi 6 (выпущенную в далеком 2001 году) имеет свои архитектурные особенности. Мы разберем по шагам несколько надежных способов реализации этой задачи, включая обработку авторизации и работу со сторонними библиотеками.

Анализ исходного кода в 1С 8.3

Для начала давайте подробно проанализируем исходный код на стороне 1С, работу которого нам необходимо воспроизвести:


Соединение = Новый HTTPСоединение(ПараметрыТелефона.ip_Адрес_Телефона, ПараметрыТелефона.Port_Телефона, ПараметрыТелефона.Login_Телефона, ПараметрыТелефона.Password_Телефона);
Запрос = Новый HTTPЗапрос("servlet?number=" + НомерТелефона);
Ответ = Соединение.Получить(Запрос);

Выясним, какие механизмы здесь задействованы:

  1. Объект HTTPСоединение: Инициализирует сессию связи с сервером. В качестве параметров конструктор принимает IP-адрес хоста, порт, а также учетные данные (логин и пароль) для прохождения базовой аутентификации (Basic Authentication).
  2. Объект HTTPЗапрос: Формирует структуру запроса. В конструктор передается относительный путь (URI) к обработчику на стороне телефона (сервлету) с GET-параметром number, содержащим номер телефона.
  3. Метод Получить(): Выполняет синхронный GET-запрос по указанному адресу и возвращает объект ответа, из которого можно прочитать тело ответа и HTTP-статус.

Наша главная задача в Delphi 6 — воссоздать этот функционал. Мы рассмотрим три различных подхода: использование стандартного набора компонентов Indy, работу через COM-объект MSXML и применение легковесной библиотеки Synapse.

---

Решение 1: Использование стандартного компонента Indy (TIdHTTP)

Библиотека Indy (Internet Direct) поставляется вместе с Delphi 6 (обычно это версии Indy 8 или Indy 9). Главный компонент для работы с веб-протоколами в этой библиотеке — TIdHTTP. Он работает на блокирующих сокетах, что делает его структуру выполнения очень похожей на линейный код в 1С.

Рассмотрим пример реализации HTTP-запроса с авторизацией через TIdHTTP:


uses
  SysUtils, Classes, IdHTTP, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;

procedure SendPhoneRequestIndy(const IPAres, Port, Login, Password, PhoneNumber: string);
var
  IdHTTP1: TIdHTTP;
  URL: string;
  ResponseText: string;
begin
  IdHTTP1 := TIdHTTP.Create(nil);
  try
    // Настраиваем базовую авторизацию (Basic Authentication)
    IdHTTP1.Request.BasicAuthentication := True;
    IdHTTP1.Request.Username := Login;
    IdHTTP1.Request.Password := Password;

    // Формируем полный URL-адрес для запроса
    // Шаблон: http://ip_address:port/servlet?number=phone_number
    URL := 'http://' + IPAres + ':' + Port + '/servlet?number=' + PhoneNumber;

    // Выполняем GET-запрос и получаем тело ответа
    try
      ResponseText := IdHTTP1.Get(URL);
      // Здесь мы можем обработать успешный ответ от телефона
    except
      on E: Exception do
      begin
        // Обработка ошибок сети или авторизации
        // Например: ShowMessage('Ошибка запроса: ' + E.Message);
      end;
    end;

  finally
    IdHTTP1.Free;
  end;
end;

Важный нюанс: В старых версиях Indy свойства авторизации могут требовать явного указания заголовков или обработки события OnAuthorization. Если сервер (телефон) отклоняет учетные данные, попробуйте принудительно передать заголовок авторизации напрямую в свойства запроса или обновите библиотеку Indy до более стабильной сборки.

---

Решение 2: Использование системного компонента MSXML (без сторонних библиотек)

Если штатный компонент Indy в вашей сборке Delphi 6 работает нестабильно или вы не хотите перегружать приложение лишними визуальными компонентами, можно воспользоваться встроенным в операционную систему Windows механизмом через технологию OLE Automation. Для этого идеально подходит объект MSXML2.XMLHTTP.

Этот способ является наиболее лаконичным, надежным и не требует установки никаких дополнительных библиотек в Delphi 6. Он использует системную библиотеку Windows, которая автоматически обновляется вместе с операционной системой.

Проанализируем пример кода с использованием MSXML:


uses
  ComObj, SysUtils;

procedure SendPhoneRequestMSXML(const IPAres, Port, Login, Password, PhoneNumber: string);
var
  XmlHttp: OleVariant;
  URL: string;
  ResponseText: string;
begin
  try
    // Создаем OLE-объект Microsoft XMLHTTP
    XmlHttp := CreateOleObject('MSXML2.XMLHTTP');

    // Формируем URL
    URL := 'http://' + IPAres + ':' + Port + '/servlet?number=' + PhoneNumber;

    // Инициализируем GET-запрос.
    // Параметры метода open:
    // 1. Метод запроса ('GET')
    // 2. Полный URL
    // 3. Асинхронность (False означает, что запрос будет выполняться синхронно, как в 1С)
    // 4. Имя пользователя для авторизации
    // 5. Пароль
    XmlHttp.open('GET', URL, False, Login, Password);

    // Отправляем запрос
    XmlHttp.send;

    // Получаем текстовый ответ от сервера
    ResponseText := XmlHttp.responseText;
    
    // Проверяем HTTP-статус ответа (200 означает успех)
    if XmlHttp.Status = 200 then
    begin
      // Успешно выполнено
    end
    else
    begin
      // Сервер вернул ошибку, например 401 (Unauthorized) или 404 (Not Found)
    end;

  except
    on E: Exception do
    begin
      // Обработка системных ошибок (например, если хост недоступен)
    end;
  end;
end;

Использование MSXML2.XMLHTTP избавляет разработчика от необходимости ручной настройки заголовков базовой авторизации, так как библиотека берет эту рутину на себя.

---

Решение 3: Использование библиотеки Synapse (модуль HTTPSend)

Еще одна прекрасная альтернатива для Delphi 6 — бесплатная библиотека для работы с сетью Synapse. В отличие от Indy, она не имеет визуальных компонентов, не требует установки в палитру Delphi и состоит из обычных pas-файлов, которые достаточно просто подключить к проекту.

Для выполнения GET-запроса нам понадобится модуль httpsend. Давайте посмотрим, как выглядит отправка запроса в данном случае:


uses
  SysUtils, Classes, httpsend;

procedure SendPhoneRequestSynapse(const IPAres, Port, Login, Password, PhoneNumber: string);
var
  HTTP: THTTPSend;
  URL: string;
  ResponseList: TStringList;
begin
  HTTP := THTTPSend.Create;
  ResponseList := TStringList.Create;
  try
    // Заполняем учетные данные авторизации
    HTTP.UserName := Login;
    HTTP.Password := Password;

    // Формируем URL
    URL := 'http://' + IPAres + ':' + Port + '/servlet?number=' + PhoneNumber;

    // Выполняем GET-запрос
    if HTTP.HTTPMethod('GET', URL) then
    begin
      // Проверяем код состояния ответа
      if HTTP.ResultCode = 200 then
      begin
        // Загружаем полученный поток в текстовый список
        ResponseList.LoadFromStream(HTTP.Document);
        // В переменной ResponseList.Text будет содержаться ответ от устройства
      end;
    end;
  finally
    ResponseList.Free;
    HTTP.Free;
  end;
end;

---

Дополнительно: Парсинг JSON-ответов в Delphi 6

Очень часто современные IP-телефоны и REST-сервисы возвращают ответы в формате JSON. В Delphi 6 нет встроенных средств для работы с этим форматом данных (так как стандарт JSON появился позже релиза шестой версии среды). Однако мы можем изящно решить эту проблему двумя способами.

Способ А: Использование Windows Script Control (JScript)

Мы можем использовать встроенный в Windows движок JScript для парсинга JSON без подключения внешних тяжелых библиотек:


uses
  ComObj;

function GetValueFromJson(const JSONString, Key: string): string;
var
  ScriptCtrl: OleVariant;
begin
  Result := '';
  try
    ScriptCtrl := CreateOleObject('MSScriptControl.ScriptControl');
    ScriptCtrl.Language := 'JScript';
    // Добавляем JS-функцию парсинга и получения значения по ключу
    ScriptCtrl.AddCode('function getValue(json, key) { var obj = eval("(" + json + ")"); return obj[key]; }');
    Result := ScriptCtrl.Run('getValue', JSONString, Key);
  except
    // Обработка ошибок парсинга невалидного JSON
  end;
end;

Способ Б: Использование библиотеки lkJSON

Для Delphi 6 отлично подходит сторонняя библиотека с открытым исходным кодом lkJSON (uLkJSON). Она написана на чистом Delphi и отлично компилируется в старых версиях среды. С ее помощью можно разбирать сложные древовидные структуры и массивы данных, получаемые в ответе на HTTP-запрос.

---

Резюме и рекомендации

Мы рассмотрели три проверенных метода реализации HTTP-запросов в Delphi 6, аналогичных логике 1С 8.3:

← На главную