Чтение сжатого gzip, deflate HTTP ответа сервера. Без ВК. Уменьши время загрузки и сократи трафик в 3 раза

В платформе 1С:Предприятие не реализовано штатного механизма декодирования ответа веб серверов, в которых присутствует gzip сжатие.
Некоторые использовали WinHttpRequest.5.1 , кто-то писал ВК.
Друзья, хватит. Вот вам решение.

Будет работать на платформе 8.3.9 + . Потому что работа с двоичными данными появилась только в них.

Многие искали ответ на этот вопрос, и тут, и на партнерском форуме, тема действительно актуальная, сейчас все работает со сжатием.

Суть метода лежала на поверхности, что такое GZIP — это формат схожих с ZIP , но отличающейся заголовочными блоками.

1) Вставляем заголовок, чтобы сервер понимал, что мы умеем принимать этот формат

Заголовки.Вставить("Accept-Encoding", "gzip");

2) Получаем ответ в виде двоичных данных 

3) Вырезаем сжатое тело (Байты с 10 по ДлинаТела — 8)

4) Формируем валидные залоговоки формата ZIP файла и добавляем к нему сжатое тело (Пример формирование валидных ZIP заголовков взят отсюда //infostart.ru/public/618906/, и доработаны)

5) Извлекаем данные с использованием ЧтениеZipФайла

 

Во вложении готовая функция, можно копировать в проект и использовать.

Если будет советы по оптимизации и улучшению, просьба в личку.

14 Comments

  1. PerlAmutor

    (0)

    Будет работать на платформе 8.3.9 + . Потому что работа с двоичными данными появилась только в них.

    Тема актуальная, т.к. сайт РБК «любит» отдавать курсы валют в Gzip формате, если запрашивать периодом. Никакие переданные ему ключи в заголовках на его поведение не влияют.

    К сожалению у меня платформа 8.3.7. Каким-то образом в ней можно извернуться так, чтобы добавить к данным заголовок (может через прямое редактирование base64 строки)?



    Кажется нашел как можно сделать на старых платформах, благодаря Александру Шпагину, но это работает только с deflate, а по поводу Gzip вопрос остается открытым:

    // сжатие решается конструкцией:
    
    ХЗ = Новый ХранилищеЗначения(НашеЗначениеКотороеНадоСжать, СжатиеДанных(9));
    СтрокаBase64 = СериализаторXDTO.XMLСтрока(ХЗ);
    СжатыеДвоичныеДанные = Base64Значение(СтрокаBase64);
    
    
    // распаковка:
    СтрокаBase64 = Base64Строка(СжатыеДвоичныеДанные);
    ХЗ = СериализаторXDTO.XMLЗначение(Тип(«ХранилищеЗначения»), СтрокаBase64);
    НашеЗначение = ХЗ.Получить();
    
    

    Показать

    Reply
  2. Malfarion

    (1) Говорят что формат deflate не используется сейчас веб серверами, хотя deflate = gzip без заголовков (чисто сжатые данные), для стандартизации все перешли на gzip.

    Reply
  3. PerlAmutor

    (1) К сожалению вариант с ХранилищемЗначения не работает, если на вход поступает Base64 строка с чистыми Deflate данными…

    Reply
  4. oyti

    Как раз совсем недавно бился над данным вопросом и временно перешел на обмен без сжатия (что так себе вариант).

    Спасибо. Будем тестировать…

    Reply
  5. PerlAmutor

    Кстати насчет обновления курсов валют с сайта РБК. Один и тот же запрос валюты может возвращать 10 раз несжатый траффик, а потом ему что-то в голову бьет и начинает возвращать снова в gzip.

    Reply
  6. fr13

    автор, спасибо! актуально

    Reply
  7. GoodZone

    Подскажите

    ИмяСжатогоФайла=»body.json»;

    это принципиально?

    Reply
  8. Malfarion

    (8) На сколько я помню нет.

    Reply
  9. GoodZone

    Просто подумал может тег body )), а так проверил все работает на ура. Очень нужная вещь.

    Reply
  10. milanse

    Есть задача данные в формате gzip распаковывать из 1С, качнул обработину, в лоб не работает. Данные содержат заголовок gzip. Убрал заголовок, отрезал хвост в соотвествии с форматом, остались только данные deflate результирующий файл 1с не распаковывает. Файл читается 7zip и far, выдает ошибку crc, но данные достает нормально….

    Может есть идеи что еще можно подшаманить ?

    Reply
  11. ui69

    Автору — спасибо! Работает четко.

    Reply
  12. boogie

    Работает прекрасно.

    Reply
  13. uno-c

    (11)

    Может есть идеи что еще можно подшаманить ?

    Посмотрите описание формата gzip: http://www.zlib.org/rfc-gzip.html Согласно этому описанию, за первыми 10 байтами не обязательно следует deflate. Перед deflate могут присутствовать также имя файла, комментарий и т.д. В случае gzip сжатого тела ответа HTTP они отсутствуют, т.е. за 10 байтами сразу начинается deflate, но для Вашей задачи нужен дальнейший разбор и проверка присутствия комментария, имени файла и проч.

    Reply
  14. milanse

    (14) спасибо посмотрю, но пока пришлось решить через ВК.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *