"Удалось обойти" - быть может это громко заявлено, но, в моем случае, страницы начали грузиться правильно, методы документа отрабатываются в полном объеме. Этому я и хочу посвятить коротенькую статью, включив в нее все необходимые алгоритмы. Пробуйте, если и у вас есть такая проблема...
Итак, для меня все страницы разделились на две категории - хорошие и плохие. Хорошие отрабатывали все методы документа (один из них использую для разделения страниц по категориям), плохие - ничего не делали, лишь генерировали кучу ошибок там, где их не было до перехода на платформу 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Документа, описанные в ней методы, увы, недоступны. Что очень печально.
Так что, если Вы, редкий читатель этой статьи (не претендующей на истину в последней инстанции), реально намного умнее меня и знаете, как решить обозначенную в статье проблему другими методами, более достойными высокого разума программиста, - поделитесь, пожалуйста, с нами этим знанием в комментариях. Я это только приветствую. Всегда полезно поучиться у "старших" товарищей... (пишу эти строки без какого-либо сарказма).