Что делать, когда методы объекта Поле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Документа, описанные в ней методы, увы, недоступны. Что очень печально.

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

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

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Сайты и интернет-магазины WEB-интеграция Системный администратор Программист Пользователь 1С:Предприятие 8 1C:Бухгалтерия 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM / LOGICSTARS. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM / LOGICSTAR разных брендов в одной информационной базе в ручном и автоматическом режиме.

42700 руб.

03.08.2020    24192    37    24    

28

WEB-интеграция Программист 1С:Предприятие 8 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

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

24000 руб.

02.02.2021    22881    68    52    

43

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

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

17568 руб.

20.12.2024    6143    27    4    

29

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

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

60000 руб.

07.05.2019    42941    76    45    

31

WEB-интеграция Загрузка и выгрузка в Excel Программист Пользователь 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Розничная и сетевая торговля (FMCG) Россия Платные (руб)

Расширение освободит вас от необходимости вручную обновлять информацию о товарах в группах ВКонтакте. Достаточно задать правила один раз, и система автоматически формирует файлы yml для дальнейшей загрузки в группы в ВК. Вы сможете легко выбирать, какие товары публиковать, создавая гибкие критерии отбора. Например, можно добавить важные для покупателей параметры: цвет, размер или другие характеристики.

12200 руб.

29.08.2025    2634    7    6    

8

Обмен с ГосИС WEB-интеграция Бухгалтер Пользователь 1С:Предприятие 8 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

5283 руб.

28.04.2016    100958    120    219    

368
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. PaStrel 132 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.База формируется?

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