В мире веб-взаимодействий, где URL-адреса играют ключевую роль, часто возникает необходимость передавать данные, содержащие специальные символы, пробелы или, что особенно актуально для русскоязычных пользователей, кириллицу. Стандартные URL-адреса не допускают использования таких символов напрямую. Именно для этого существует URL-кодирование, или так называемое "процентное кодирование" (percent-encoding).
Однако, платформа 1С 7.7, в отличие от своих более современных версий, не имеет встроенных функций для автоматического URL-кодирования и декодирования. Это создает определенные сложности для разработчиков. В этой статье мы подробно рассмотрим различные подходы к решению этой задачи, основываясь на опыте сообщества 1С и дополнительной информации.
Мы вместе разберем несколько методов, от ручного создания таблиц соответствий до использования внешних компонент, и выясним, какой из них будет наиболее подходящим для вашей ситуации.
Начнем с базового, но трудоемкого метода, который часто применяют в 1С 7.7, когда нет готовых инструментов. Мы рассмотрим, как можно вручную заменить символы на их закодированные эквиваленты.
Этот подход требует создания таблицы соответствий между исходными символами (например, русскими буквами) и их закодированным представлением. В сообщении на форуме был предложен пример функции для обратного процесса – декодирования. Давайте проанализируем его, чтобы понять принцип, а затем подумаем, как реализовать кодирование.
Рассмотрим пример функции urldecode, которая преобразует закодированные последовательности обратно в читаемый текст:
Функция urldecode(Стр)
Стр = Врег(Стр);
Стр = СтрЗаменить(Стр,"\U0430","а");
Стр = СтрЗаменить(Стр,"\U0431","б");
Стр = СтрЗаменить(Стр,"\U0432","в");
Стр = СтрЗаменить(Стр,"\U0433","г");
Стр = СтрЗаменить(Стр,"\U0434","д");
Стр = СтрЗаменить(Стр,"\U0435","е");
Стр = СтрЗаменить(Стр,"\U0451","ё");
Стр = СтрЗаменить(Стр,"\U0436","ж");
Стр = СтрЗаменить(Стр,"\U0437","з");
Стр = СтрЗаменить(Стр,"\U0438","и");
Стр = СтрЗаменить(Стр,"\U0439","й");
Стр = СтрЗаменить(Стр,"\U043A","к");
Стр = СтрЗаменить(Стр,"\U043B","л");
Стр = СтрЗаменить(Стр,"\U043C","м");
Стр = СтрЗаменить(Стр,"\U043D","н");
Стр = СтрЗаменить(Стр,"\U043E","о");
Стр = СтрЗаменить(Стр,"\U043F","п");
Стр = СтрЗаменить(Стр,"\U0440","р");
Стр = СтрЗаменить(Стр,"\U0441","с");
Стр = СтрЗаменить(Стр,"\U0442","т");
Стр = СтрЗаменить(Стр,"\U0443","у");
Стр = СтрЗаменить(Стр,"\U0444","ф");
Стр = СтрЗаменить(Стр,"\U0445","х");
Стр = СтрЗаменить(Стр,"\U0446","ц");
Стр = СтрЗаменить(Стр,"\U0447","ч");
Стр = СтрЗаменить(Стр,"\U0448","ш");
Стр = СтрЗаменить(Стр,"\U0449","щ");
Стр = СтрЗаменить(Стр,"\U044A","ъ");
Стр = СтрЗаменить(Стр,"\U044B","ы");
Стр = СтрЗаменить(Стр,"\U044C","ь");
Стр = СтрЗаменить(Стр,"\U044D","э");
Стр = СтрЗаменить(Стр,"\U044E","ю");
Стр = СтрЗаменить(Стр,"\U044F","я");
Стр = СтрЗаменить(Стр,"\U0410","А");
Стр = СтрЗаменить(Стр,"\U0411","Б");
Стр = СтрЗаменить(Стр,"\U0412","В");
Стр = СтрЗаменить(Стр,"\U0413","Г");
Стр = СтрЗаменить(Стр,"\U0414","Д");
Стр = СтрЗаменить(Стр,"\U0415","Е");
Стр = СтрЗаменить(Стр,"\U0401","Ё");
Стр = СтрЗаменить(Стр,"\U0416","Ж");
Стр = СтрЗаменить(Стр,"\U0417","З");
Стр = СтрЗаменить(Стр,"\U0418","И");
Стр = СтрЗаменить(Стр,"\U0419","Й");
Стр = СтрЗаменить(Стр,"\U041A","К");
Стр = СтрЗаменить(Стр,"\U041B","Л");
Стр = СтрЗаменить(Стр,"\U041C","М");
Стр = СтрЗаменить(Стр,"\U041D","Н");
Стр = СтрЗаменить(Стр,"\U041E","О");
Стр = СтрЗаменить(Стр,"\U041F","П");
Стр = СтрЗаменить(Стр,"\U0420","Р");
Стр = СтрЗаменить(Стр,"\U0421","С");
Стр = СтрЗаменить(Стр,"\U0422","Т");
Стр = СтрЗаменить(Стр,"\U0423","У");
Стр = СтрЗаменить(Стр,"\U0424","Ф");
Стр = СтрЗаменить(Стр,"\U0425","Х");
Стр = СтрЗаменить(Стр,"\U0426","Ц");
Стр = СтрЗаменить(Стр,"\U0427","Ч");
Стр = СтрЗаменить(Стр,"\U0428","Ш");
Стр = СтрЗаменить(Стр,"\U0429","Щ");
Стр = СтрЗаменить(Стр,"\U042A","Ъ");
Стр = СтрЗаменить(Стр,"\U042B","Ы");
Стр = СтрЗаменить(Стр,"\U042C","Ь");
Стр = СтрЗаменить(Стр,"\U042D","Э");
Стр = СтрЗаменить(Стр,"\U042E","Ю");
Возврат Стр;
КонецФункции
Как мы видим, функция urldecode использует многократные вызовы метода СтрЗаменить() для замены Unicode-последовательностей (например, \U0430) на соответствующие русские буквы. Функция Врег(Стр) приводится в примере, но ее необходимость для данного конкретного декодирования Unicode-последовательностей неочевидна, если все замены указаны для обоих регистров.
Для создания функции кодирования по такому же принципу нам потребуется обратная логика:
%D0%B0 или \U0430, в зависимости от желаемого формата).Важно понимать: этот метод крайне трудоемок, подвержен ошибкам и не является универсальным, так как требует ручного добавления всех возможных символов и их кодировок. Он также не соответствует стандартному URL-кодированию, которое использует байты UTF-8. Тем не менее, для очень ограниченного набора символов и специфических задач он может быть применен.
Этот подход является более универсальным и соответствующим стандартам URL-кодирования. Мы разберем его по шагам, используя пример из обсуждения.
Ключевая идея: сначала преобразовать текст в последовательность байтов в кодировке UTF-8, а затем каждый "небезопасный" байт представить в шестнадцатеричном виде, предваряя знаком процента (%).
Рассмотрим подробнее пример кода:
Процедура Сформировать()
Хекс = "0123456789ABCDEF";
СтрокаУТФ8 = глСервис.DecodeToUTF8(ВыбСтрока);
РС = СтрДлина(СтрокаУТФ8);
Результат = "";
Для ы=1 По РС Цикл
Символ = Сред(СтрокаУТФ8,ы,1);
СимволКод = КодСимв(Символ);
СтаршийРазряд = Цел(СимволКод/16);
МладшийРазряд = СимволКод - СтаршийРазряд*16;
Результат = Результат + "%"+
Сред(Хекс,СтаршийРазряд+1,1)+
Сред(Хекс,МладшийРазряд+1,1);
КонецЦикла;
Форма.тРезультат.Заголовок(Результат);
Т = СоздатьОбъект("Текст");
Т.ДобавитьСтроку(ВыбСтрока+РазделительСтрок+Результат);
Т.Записать("e:\rez");
КонецПроцедуры // Сформировать()
Давайте проанализируем этот код:
Хекс содержит строку со всеми шестнадцатеричными цифрами. Она нужна нам для преобразования числовых значений в их символьное представление.СтрокаУТФ8 = глСервис.DecodeToUTF8(ВыбСтрока); является критически важным шагом. В 1С 7.7 нет встроенной функции для прямой работы с UTF-8. Здесь используется внешняя вспомогательная функция глСервис.DecodeToUTF8(), которая, по всей видимости, берет строку в текущей кодировке 1С (чаще всего Windows-1251) и преобразует ее в строку, где каждый символ представляет собой один байт UTF-8. Это означает, что многобайтовые символы UTF-8 (например, кириллица) будут представлены несколькими "псевдо-символами" в строке СтрокаУТФ8.СтрокаУТФ8.
Символ = Сред(СтрокаУТФ8,ы,1); - получаем текущий "байт".СимволКод = КодСимв(Символ); - получаем числовой код этого "байта".СтаршийРазряд = Цел(СимволКод/16); - вычисляем старший разряд шестнадцатеричного числа.МладшийРазряд = СимволКод - СтаршийРазряд*16; - вычисляем младший разряд.Результат = Результат + "%"+ Сред(Хекс,СтаршийРазряд+1,1)+ Сред(Хекс,МладшийРазряд+1,1); - формируем закодированную последовательность. К результату добавляется знак процента (%), а затем два символа, соответствующих старшему и младшему разрядам из строки Хекс. Например, байт с кодом 32 (пробел) станет %20. Кириллический символ "к", который в UTF-8 может быть представлен байтами D0 и BA, превратится в %D0%BA.Этот метод является более правильным и универсальным, так как он следует принципам URL-кодирования, основанным на UTF-8. Однако, его успешное применение полностью зависит от наличия и корректной работы внешней функции глСервис.DecodeToUTF8(). Без нее этот подход не будет работать.
Наиболее удобным, надежным и соответствующим стандартам способом является использование внешних компонент (ВК). Как упоминается в обсуждении, существуют готовые ВК, которые предоставляют необходимые функции.
Преимущества использования ВК:
Карлик.ToURL(Строка) для кодирования и Карлик.FromURL(Строка) для декодирования.В качестве примера была упомянута ВК "Карлик", предоставляющая методы Карлик.FromURL() и Карлик.ToURL(). Если у вас есть возможность использовать внешние компоненты, это, безусловно, рекомендуемый путь.
Процесс работы с внешней компонентой:
.dll или .ocx).regsvr32.exe).
Попытка
Карлик = СоздатьОбъект("AddIn.Карлик"); // Имя объекта может отличаться
Исключение
Сообщить("Не удалось загрузить внешнюю компоненту 'Карлик'.");
Возврат;
КонецПопытки;
ИсходнаяСтрока = "Привет, мир!";
ЗакодированнаяСтрока = Карлик.ToURL(ИсходнаяСтрока); // Например, "%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82%2C%20%D0%BC%D0%B8%D1%80%21"
ДекодированнаяСтрока = Карлик.FromURL(ЗакодированнаяСтрока); // Вернет "Привет, мир!"
Обратите внимание: автор компоненты "Карлик" в своем сообщении предупреждает, что сборка такой ВК может быть достаточно сложной, если вы решите компилировать ее из исходников. Однако, если вы найдете уже готовую и скомпилированную версию, процесс ее использования значительно упростится.
Мы рассмотрели несколько подходов к решению проблемы URL-кодирования в 1С 7.7. Подведем итоги:
глСервис.DecodeToUTF8()) для корректного преобразования строки в байты UTF-8. Без такой функции реализация становится значительно сложнее.При выборе метода всегда учитывайте, какая именно кодировка ожидается на принимающей стороне (чаще всего это UTF-8) и какой тип кодирования вам нужен – для всего URL или только для его компонентов (например, параметров запроса). В большинстве случаев для параметров запроса требуется более агрессивное кодирование, которое обрабатывает больше специальных символов.
Надеемся, что этот подробный разбор поможет вам успешно реализовать URL-кодирование в ваших решениях на 1С 7.7!
← К списку