Распознавание госномеров через API и 1С

JSON1С 8.3 Ответ HTTP Временный файл

Бухгалтерия элеватора, ред. 3

Добрый день! Есть сервис API для бесплатного распознавания госномеров: https://data.av100.ru/docs/numberrecognize. С его помощью решили распознавать госномера машин, которые проходят весовой контроль. То есть при взвешивании с IP-камеры сохраняется скриншот, а потом по этому скриншоту 1С должна распознать номер и вывести его. Описание API и передача параметров вроде ясна. Однако в ответ я получаю сообщение об ошибке "Изображение для поиска не найдено". Во временном файле определенно хранятся данные картинки и передаются. Но не пойму, что не так. Может я картинку не так обрабатываю или запрос HTTP не верный? Пробовала в разной кодировке отправлять данные, но ошибка вообще не менялась, как будто картинка действительно не доходит до API. Что делать, уже без понятия. Может есть у кого-то идеи какие-нибудь. Кстати, попробовала на postman создать POST-запрос. Там все работает. Ниже приведен код передачи картинки в API:

    Файл = ("gosnomer.jpg");
    ДД = Новый ДвоичныеДанные(Файл);
    Строка64 = Base64Строка(ДД);
    имяФайлаОтправки = ПолучитьимяВременногоФайла("txt");
    boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");

    ЗаписьТекста = Новый ЗаписьТекста(имяФайлаОтправки, КодировкаТекста.UTF8, Символы.ПС, Ложь);
    ЗаписьТекста.ЗаписатьСтроку("--" + boundary);
    ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""image""; filename=""photo.jpg""" + Символы.ПС);
    ЗаписьТекста.ЗаписатьСтроку("Content-Type: image/jpeg");
    ЗаписьТекста.ЗаписатьСтроку("");
    ЗаписьТекста.ЗаписатьСтроку(Строка64);
    ЗаписьТекста.ЗаписатьСтроку("--" + boundary + "--");
    ЗаписьТекста.Закрыть();

    ФайлОтправки = Новый Файл(имяФайлаОтправки);
    РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());

    Заголовки = Новый Соответствие();
    Заголовки.Вставить("Content-Type", "multipart/form-data, boundary=" + boundary);
    Заголовки.Вставить("Content-Lenght", РазмерФайлаОтправки);

    ЗапросHTTP = Новый HTTPЗапрос("/numberrecognize.ashx?key=60b84eaf-aa77-474b-96fe-ff7e0fbdcd2a", Заголовки);
    ЗапросHTTP.УстановитьИмяФайлаТела(имяФайлаОтправки);

    Соединение = Новый HTTPСоединение("data.av100.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL());
    ОтветHTTP = Соединение.ОтправитьДляОбработки(ЗапросHTTP);
    ОтветСтрокой = ОтветHTTP.ПолучитьТелоКакСтроку();

Ответы (1 шт):

Автор решения: Laukhin Andrey

Удалось заставить код работать. По порядку:

  1. Content-Lenght написано с ошибкой, правильно Content-Length.
  2. Если используется кодировка UTF-8, то в теле запроса не должно быть сигнатуры BOM.
    Это известная проблема. Так как будущее тело запроса предварительно сохраняется в файл (с кодировкой UTF-8), то в начало будет добавлен маркер из трех байт. По ссылке выше можно найти ряд решений. Есть вариант не записывать в файл, а сформировать строку и использовать метод УстановитьТелоИзСтроки(), в котором есть параметр <ИспользоватьBOM>. Это просто для информации. В нашем же случае, можно использовать ANSI.
  3. Документация к API чуть-чуть сбивает с толку фразой "изображение с расширением .jpg". На самом деле, имеется в виду формат JPEG, а ключевой момент состоит в том, что это POST-параметр, а не файл-вложение. Поэтому из заголовка нужно убрать filename=""photo.jpg"", тогда сервер сможет правильно интерпретировать данные.
    + Символы.ПС здесь тоже лишнее.
Файл = ("gosnomer.jpg");
ДД = Новый ДвоичныеДанные(Файл);
Строка64 = Base64Строка(ДД);
имяФайлаОтправки = ПолучитьимяВременногоФайла("txt");

boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");

ЗаписьТекста = Новый ЗаписьТекста(имяФайлаОтправки, КодировкаТекста.ANSI, Символы.ПС, Ложь);
ЗаписьТекста.ЗаписатьСтроку("--" + boundary);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""img""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: image/jpeg");
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку(Строка64);
ЗаписьТекста.ЗаписатьСтроку("--" + boundary + "--");
ЗаписьТекста.Закрыть();

ФайлОтправки = Новый Файл(имяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());

Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "multipart/form-data, boundary=" + boundary);
Заголовки.Вставить("Content-Length", РазмерФайлаОтправки);

ЗапросHTTP = Новый HTTPЗапрос("/numberrecognize.ashx?key=60b84eaf-aa77-474b-96fe-ff7e0fbdcd2a", Заголовки);
ЗапросHTTP.УстановитьИмяФайлаТела(имяФайлаОтправки);

Соединение = Новый HTTPСоединение("data.av100.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL());
ОтветHTTP = Соединение.ОтправитьДляОбработки(ЗапросHTTP);
ОтветСтрокой = ОтветHTTP.ПолучитьТелоКакСтроку();
→ Ссылка