Что делать, когда методы объекта Поле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    1514    1    1    

4

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

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

36000 руб.

03.08.2020    18560    20    22    

18

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

Интеграция 1С и Битрикс 24. Разработка имеет двухстороннюю синхронизацию 1С и Bitrix24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (платформа начиная с 8.3.23): 1С:Управление торговлей, 1С:Управление Нашей фирмой 3, 1С:Комплексная автоматизация 2, Объединенное решение: Модуль 1С:CRM 3 (3.0.21.3) +1С:ERP Управление предприятием 2. При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

7200 руб.

04.05.2021    20700    13    19    

18

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    459    2    0    

5

Обмен с ГосИС 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

2400 руб.

28.04.2016    92157    184    217    

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