Что делать, когда методы объекта ПолеHTMLДокумента.Документ (УФ) недоступны?

27.02.23

Интеграция - WEB-интеграция

Начиная с версии 8.3.14 некорректно загружаются некоторые веб-страницы в поле HTML-документа на УФ - методы ПолеHTMLДокумента.Документ недоступны. Методом "научного втыка" удалось обойти этот глюк системы.

"Удалось обойти" - быть может это громко заявлено, но, в моем случае, страницы начали грузиться правильно, методы документа отрабатываются в полном объеме. Этому я и хочу посвятить коротенькую статью, включив в нее все необходимые алгоритмы. Пробуйте, если и у вас есть такая проблема...

Итак, для меня все страницы разделились на две категории - хорошие и плохие. Хорошие отрабатывали все методы документа (один из них использую для разделения страниц по категориям), плохие - ничего не делали, лишь генерировали кучу ошибок там, где их не было до перехода на платформу 8.3.14. Если кто-то думает, что ошибки, возможно, ушли с обновлениями, - увы, нет. Платформа 8.3.22 показала такой же результат.

Собственно, самих алгоритмов немного, в комментариях они вряд ли нуждаются. Основные действия происходят в событии HTMLДокументСформирован:

 

&НаКлиенте
Процедура HTMLДокументСформирован(Элемент)

	Документ = Элемент.Документ;
	Если Документ.readyState <> "complete" Тогда
		Возврат;
	КонецЕсли;
	
	Если ЭтоПлохаяСтраница() Тогда
		//	Этот фрагмент должен выполниться один раз и следует предпринять
		//	дополнительные шаги во избежание зацикливания вызова HTMLДокументСформирован()
		СтруктураURI = НаКлиенте.СтруктураURI(АдресРесурса);
		Результат = GetКакТекст(АдресРесурса);
		Результат = СтрЗаменить(Результат, "<head>", "<head><base href=""" + СтруктураURI.База + """>");
		HTML = Результат;
		Возврат;
	КонецЕсли;
	
	// прочие алгоритмы
	
КонецПроцедуры



&НаКлиенте
Функция ЭтоПлохаяСтраница()
	
	Попытка
		Получены = Элементы.HTML.Документ.querySelector("html");
		Возврат Ложь;
	Исключение
		Возврат Истина;
	КонецПопытки;
	
КонецФункции


&НаКлиенте
Функция СтруктураURI(Знач СтрокаURI)
		
	//	Выражение = <URI>
	//
	//	Левая скобка параметра = <
	//	Правая скобка параметра = >
	//	Шаблон имени = [А-ЯA-Z][-_ А-Яа-я0-9A-Za-z]*?
	//
	//	+-	<URI> = ^(?:<Схема>:)?(?:\/\/<Источник>)?<Путь>(?:\?<Запрос>)?(?:#<Фрагмент>)?
	//	++	<Схема> = ((?:[^:\/?#\n]+)?)
	//	+-	<Источник> = (?:<Логин>:<Пароль>@)?<Хост>(?::<Порт>)?
	//	++	<Путь> = ([^?#\n]*/?)
	//	++	<Запрос> = ([^#\n]*)
	//	++	<Фрагмент> = (.*)
	//	++	<Логин> = ([^\/?#@:\n]*)
	//	++	<Пароль> = ([^\/?#@:\n]*)
	//	++	<Хост> = ([^\/?#@:\n]*)
	//	++	<Порт> = ([^\/?#@:\n]*)


	idПорт = "([^\/?#@:\n]*)";
	idХост = "([^\/?#@:\n]*)";
	idПароль = "([^\/?#@:\n]*)";
	idЛогин = "([^\/?#@:\n]*)";
	idФрагмент = "(.*)";
	idЗапрос = "([^#\n]*)";
	idПуть = "([^?#\n]*/?)";
	idИсточник = "(?:" + idЛогин + ":" + idПароль + "@)?" + idХост + "(?::" + idПорт + ")?";
	idСхема = "((?:[^:\/?#\n]+)?)";
	idURI = "^(?:" + idСхема + ":)?(?:\/\/" + idИсточник + ")?" + idПуть + "(?:\?" + idЗапрос + ")?(?:#" + idФрагмент + ")?";
	idPattern = idURI;
		
	RegExp = Новый COMОбъект("VBScript.RegExp");
		
	RegExp.Multiline = Истина;
	RegExp.Global = Истина;
	RegExp.IgnoreCase = Истина;
	RegExp.Pattern = idPattern;
		
	Результат = Новый Структура;
	Найдено = RegExp.Execute(СтрокаURI);
	
	Если Найдено <> Неопределено  Тогда
		Стр = Найдено.Item(0);
		
		Результат.Вставить("Схема ", Нрег(Стр.SubMatches(0)));
		Результат.Вставить("Логин", Стр.SubMatches(1));
		Результат.Вставить("Пароль", Стр.SubMatches(2));
		Результат.Вставить("Хост", Стр.SubMatches(3));
		Результат.Вставить("Порт", Стр.SubMatches(4));
		Результат.Вставить("Путь", Стр.SubMatches(5));
		Результат.Вставить("Запрос", Стр.SubMatches(6));
		Результат.Вставить("Фрагмент", Стр.SubMatches(7));
	КонецЕсли;
	
	
	База = "";
	Если НЕ ПустаяСтрока(Результат.Схема) Тогда
		База = База + Результат.Схема + "://";
	КонецЕсли;
	Если НЕ ПустаяСтрока(Результат.Логин) Тогда
		База = База + Результат.Логин + ":" + Результат.Пароль + "@";
	КонецЕсли;
	Если НЕ ПустаяСтрока(Результат.Хост) Тогда
		База = База + Результат.Хост;
	КонецЕсли;
	Если НЕ ПустаяСтрока(Результат.Порт) Тогда
		База = База + ":" + Результат.Порт;
	КонецЕсли;

	спПуть = СтрокаВМассив(Результат.Путь, "/");
	Индекс = спПуть.ВГраница();
	Файл = "";
	Если Индекс >= 0 Тогда
		Файл = спПуть[Индекс];
	КонецЕсли;
	
	спПуть = СтрокаВМассив(Файл, ".");
	Индекс = спПуть.ВГраница();
	Расширение = "";
	Если Индекс >= 1 Тогда
		Расширение = спПуть[Индекс];
	КонецЕсли;
	
	Каталог = База + Лев(Результат.Путь, СтрДлина(Результат.Путь)-СтрДлина(Файл));
	
	Результат.Вставить("База", База);
	Результат.Вставить("Каталог", Каталог);
	Результат.Вставить("Файл", Файл);
	Результат.Вставить("Расширение", Расширение);
	Результат.Вставить("URI", СтрокаURI);
	
    Возврат Результат;
 
КонецФункции


&НаСервереБезКонтекста
Функция GetКакТекст(URL)
	
	Возврат КоннекторHTTP.КакТекст(КоннекторHTTP.Get(URL));
	
КонецФункции


&НаКлиенте
Функция СтрокаВМассив(Знач Стр, Разделитель) Экспорт
	
	сп = Новый Массив;
	
	ДлинаРазделителя = СтрДлина(Разделитель);
	Если ДлинаРазделителя <> 0  Тогда
		Пока СтрДлина(Стр) > 0 Цикл
			Поз = Найти(Стр, Разделитель);
			Если Поз = 0 
			Тогда
				сп.Добавить(СокрЛП(Стр));
				Стр="";
			Иначе         
				сп.Добавить(СокрЛП(Лев(Стр, Поз-1)));
				Стр = СокрЛП(Сред(Стр, Поз+ДлинаРазделителя));
			КонецЕсли;
		КонецЦикла;
	Иначе
		ДлинаСтроки = СтрДлина(Стр);
		Для Инд = 1 По ДлинаСтроки Цикл
			сп.Добавить(Сред(Стр, Инд, 1));
		КонецЦикла;
	КонецЕсли;

	Возврат сп;	
	
КонецФункции

 

В приведенном алгоритме я все собрал до кучи, на клиенте - для демонстрации, не судите строго.

Использован КоннекторHTML Владимира Бондаревского для получения тела HTML-документа. При желании, замените чем-то другим.

 

Несколько дней спустя...

Дополнение: пытался сделать код более лаконичным. Когда страница сформирована, код HTML можно получить из документа, и тогда нет необходимости повторно загружать его с помощью КоннектораHTML (или каким-то другим способом). "Брюки превращаются...":

 


&НаКлиенте
Процедура HTMLДокументСформирован(Элемент)

	Документ = Элемент.Документ;
	Если Найти(Элемент.Документ.location.hash, "v8menu://") <> 0  Тогда
		HTML = "";
		Возврат
	КонецЕсли;
	
	Если Документ.readyState <> "complete" Тогда
		Возврат;
	КонецЕсли;
	
	Если ЭтоПлохаяСтраница() Тогда
		
		СтруктураURI = НаКлиенте.СтруктураURI(АдресРесурса);
		КодHTML = Документ.documentElement.outerHTML;
		КодHTML = СтрЗаменить(КодHTML, "<head>", "<head><base href=""" + СтруктураURI.База + """>");
		HTML = КодHTML;
		Возврат;
		
	КонецЕсли;

	//  Далее код

КонецПроцедуры

 

Это! - не работает. Я сравнил полученный из документа код HTML с тем, что получаем, обратившись к КоннекторуHTML (альтернативная загрузка). Они - разные. Так что, попытка оптимизации кода привела к плачевному результату.

 

Напоследок, обращаюсь к тем редким читателям, которые ставят минус этой публикации, не пояснив почему. Мне, например, было важно, чтобы все страницы грузились в ПолеHTMLДокумента правильно, без ошибок. Среди них информационные ресурсы, очень интересные программистам. Вот хотя бы взять пример страницы Document  с описанием свойств и методов документа HTML. После загрузки страницы в ПолеHTMLДокумента, описанные в ней методы, увы, недоступны. Что очень печально.

Так что, если Вы, редкий читатель этой статьи (не претендующей на истину в последней инстанции), реально намного умнее меня и знаете, как решить обозначенную в статье проблему другими методами, более достойными высокого разума программиста, - поделитесь, пожалуйста, с нами этим знанием в комментариях. Я это только приветствую. Всегда полезно поучиться у "старших" товарищей... (пишу эти строки без какого-либо сарказма).

Вступайте в нашу телеграмм-группу Инфостарт

См. также

Оптовая торговля Розничная торговля WEB-интеграция 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Платные (руб)

Онлайн-заказ - это решение для автоматизации процесса оформления заказов на сайте в торговых организациях. Продукт обеспечивает легкое взаимодействие между компанией и клиентами через веб-интерфейс, интегрированный с 1С:Предприятие. Система позволяет снизить операционные расходы, повысить лояльность клиентов и оптимизировать работу отдела продаж.

57600 руб.

26.11.2024    5936    4    3    

7

WEB-интеграция Программист Бизнес-аналитик 1С v8.3 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Оптовая торговля, дистрибуция, логистика ИТ-компания Платные (руб)

Модуль "Экспортер" — это расширение для 1С, предназначенное для автоматизации процессов выгрузки данных. Оно позволяет эффективно извлекать, преобразовывать и передавать данные из систем 1С в интеграционную платформу Spot2D. Подсистема упрощает настройку, снижает количество ручных операций и обеспечивает удобный контроль данных.

14400 руб.

20.12.2024    3306    17    2    

19

WEB-интеграция 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Оптовая торговля, дистрибуция, логистика Россия Платные (руб)

В расширении реализован механизм интеграции между системой поставщика и Личным кабинетом СДТ. Реализован обмен заказами и реализациями (накладными), предусмотрено отслеживание статусов документов. Расширение предназначено для 1С:УТ 11.4.

35856 руб.

27.11.2024    1773    1    0    

1

Обмен с ГосИС WEB-интеграция Бухгалтер Пользователь 1С v8.3 Управляемые формы 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия государственного учреждения 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Платные (руб)

Обработка является альтернативой механизму, разработанному фирмой 1С и заполняющему реквизиты контрагента по ИНН или наименованию. Не требуется действующей подписки ИТС. Вызывается как внешняя дополнительная обработка, т.е. используется, непосредственно, из карточки контрагента. Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС (egrul.nalog.ru) для БП 2.0, БП 3.0, БГУ 1.0, БГУ 2.0, УТ 10.3, УТ 11.x, КА 1.1, КА 2.x, УПП 1.x, ERP 2.x, УНФ 1.5, УНФ 1.6, УНФ 3.0, ДО 2.1

5196 руб.

28.04.2016    97269    109    218    

359

Обмен с ГосИС Мастера заполнения WEB-интеграция Бухгалтер Пользователь 1С v8.3 Бухгалтерский учет Оперативный учет Управляемые формы 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Платные (руб)

Универсальное расширение конфигурации для автоматической загрузки и заполнения реквизитов контрагентов (партнеров) из ОГРН для 1С:ERP Управление предприятием 2 (1С:ERP Управление предприятием 2, редакция 2.4), 1С:ERP Управление предприятием 2 (1С:ERP Управление предприятием 2, редакция 2.2), 1С:Управление торговлей 8 (Управление торговлей, редакция 11.5), 1С:Управление торговлей 8 (Управление торговлей, редакция 11.4), 1С:Управление торговлей 8 (Управление торговлей, редакция 11.3), 1С:Управление торговлей 8 (Управление торговлей, редакция 11.2), 1С:Комплексная автоматизация 8 (1С:Комплексная автоматизация, редакция 2.4), 1С:Комплексная автоматизация 8 (1С:Комплексная автоматизация, редакция 2.2), 1С:Комплексная автоматизация 8 (1С:Комплексная автоматизация, редакция 2.0) и 1С:Бухгалтерия 8 (Бухгалтерия предприятия, редакция 3.0).

5000 руб.

08.11.2017    69349    415    298    

84

WEB-интеграция Программист 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

Внешняя обработка разработана для автоматизации передачи данных между сервисом Vetmanager с 1С: Бухгалтерия 3.0. Решение позволяет загружать документы и справочники из Ветменеджер в 1С:Бухгалтерию, сокращая время на ручной ввод данных и минимизируя ошибки.

12000 руб.

02.02.2021    20187    58    52    

36
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. user925427 130 27.02.23 23:49 Сейчас в теме
Дьявол, как обычно, в деталях. Суть решения, если не ошибаюсь, в этой строке: Результат = СтрЗаменить(Результат, "<head>", "<head><ba se href=""" + СтруктураURI.База + """>"); Очередная недокументированная особенность объекта 1С. Пока не столкнёшься, не узнаешь, на заметку взять стоит. Автору плюс за желание поделиться с сообществом.
2. romasna 326 28.02.23 10:25 Сейчас в теме
3. andryandry 100 19.08.25 16:01 Сейчас в теме
поясните - а какого вида строка СтруктураURI.База формируется?

пытаюсь "победить" ошибки в поле Документ по линуксом....
Для отправки сообщения требуется регистрация/авторизация