В head стоит href="article/", а выше появился base с адресом другого раздела. В исходнике строка canonical выглядит прежней, однако браузер разрешает её относительно новой базы. Диагностика должна сравнивать буквальный атрибут с вычисленным абсолютным URL.
Почему буквальный href не показывает полный адрес
Относительный адрес требует базы разрешения. Тег base влияет на такие ссылки, поэтому проверка одного getAttribute не показывает весь результат. Для canonical удобнее явно сформировать абсолютный адрес на уровне серверного шаблона.
MDN описывает разрешение относительных ссылок относительно базового URL, включая ссылки от корня. Официальная документация.
Строки article/, /article/ и https://example.com/article/ задают разные правила построения адреса. Первая использует текущий каталог базы, вторая — её корень, третья задаёт полный адрес. Если в документе появляется base на другом домене, первые две строки могут начать вести туда. Canonical нередко создаётся отдельным плагином, который не знает о настройке base в теме. Поэтому читающий исходник человек видит прежнюю строку, а браузер получает другое вычисленное назначение.
Постройте таблицу разрешения относительно base
Учебные сценарии в таблице задают ожидаемое поведение; фактические ответы своего сайта заносите отдельно.
| Сценарий | Отличие | Решение | Проверка |
|---|---|---|---|
| href="article/" | База /docs/ | Получится /docs/article/ | Проверить document.baseURI |
| href="/article/" | База на другом хосте | Корень другого хоста | Слеш не фиксирует домен |
| Абсолютный HTTPS URL | Любая база | Адрес явно задан | Предпочтительный вариант |
| Base меняет скрипт | Исходник и DOM различаются | Повторить после загрузки | Найти генератор |
Добавьте в учебную таблицу базу https://example.com/docs/ и базу https://cdn.example/assets/. Разрешите каждую относительную строку отдельно. Это можно сделать через new URL(relative, base).href без изменения живой страницы. Для первого случая article/ станет /docs/article/, а /article/ останется на корне example.com. Для второго случая изменится хост. Сам расчёт является диагностическим упражнением: после него всё равно нужно посмотреть настоящий document.baseURI, поскольку фактический документ может содержать другой base или не содержать его вовсе.
Три значения для проверки в браузере
В консоли браузера сравните document.baseURI, getAttribute("href") и свойство href найденного link. Затем проверьте порядок элементов head и исходный HTML; base мог появиться только после выполнения скрипта.
Для найденного link сравните getAttribute("href") с его свойством href. Первый возвращает записанное значение, второе показывает вычисленный адрес элемента в браузере. Дополнительно сохраните document.baseURI. Если эти данные противоречат ожиданию, найдите base в head и выясните источник его появления. Проверяйте все canonical-элементы: выбор только первого скрывает дублирующий вывод. Такой тест не доказывает, что поисковик уже выбрал иной URL; он подтверждает конкретную неоднозначность или неправильное разрешение в текущем документе.
Проверьте порядок head и поздние изменения DOM
Для учебного документа с base https://example.com/docs/ сравните article/ и /article/. Первый адрес сохраняет путь docs, второй начинает путь от корня того же хоста. Затем смените хост базы и убедитесь, почему абсолютный canonical надёжнее.
Сначала смотрите сырой HTML, затем DOM после загрузки приложения. Если base вставляет скрипт, вычисленные ссылки могут измениться уже после получения документа. Проверьте момент изменения через наблюдение DOM или отключение соответствующего скрипта на тестовой копии. Особое внимание уделите шаблонам документации и прокси-просмотра, где base используется намеренно. В них относительные изображения и ссылки могут зависеть от этой настройки. Исправлять всю страницу удалением base без проверки зависимостей рискованно даже при явной ошибке canonical.
Исправление абсолютного canonical без поломки ресурсов
Исправьте генератор canonical так, чтобы он выдавал абсолютный производственный URL. Сам base меняйте лишь после проверки остальных относительных ресурсов, ссылок и форм: удаление этого тега может нарушить другой сценарий.
Для canonical сформируйте абсолютный адрес из проверенного публичного домена и пути страницы. Не берите домен из непроверенного входного заголовка запроса, если это позволяет получить чужой адрес. Отдельно убедитесь, что сборка staging не встроила свой хост в production. Если base нужен другим ресурсам, оставьте его и исправьте только генератор canonical. Если base признан ошибочным, перечислите относительные ресурсы, меню и action форм, которые требуется проверить после удаления. Так решение не ограничивается зелёной строкой SEO-отчёта.
Приёмка на разных путях и окружениях
Начальный слеш разрешается от корня выбранной базы, но не фиксирует домен. Поэтому href="/article/" всё ещё может привести на чужой хост при другом base.
Откройте главную, вложенную страницу и адрес с параметром, если такой вариант поддерживается. На каждом canonical должен содержать согласованный полный URL, а вычисленное href — совпадать с буквальным абсолютным значением. Затем пройдите относительные ссылки меню и отправку тестовой формы без реального сообщения, если проверяется её action. Проверьте хосты ресурсов в Network. Приёмка должна подтвердить, что исправление адреса не перенесло изображения на неправильный путь и не разрушило предусмотренное использование базы в остальных элементах.
Отдельный тест для URL без завершающего слеша
При отсутствии явного base базовым становится адрес документа. Для https://example.com/docs и https://example.com/docs/ относительное article/ может разрешаться по-разному, потому что первый адрес выглядит как файл, второй — как каталог. Сначала выясните, перенаправляет ли сервер один вариант на другой, затем вычисляйте адрес относительно фактического конечного URL. Проверьте обе формы прямым входом, особенно если reverse proxy меняет путь. Если генератор выдаёт абсолютный canonical, это различие больше не влияет на его href, но по-прежнему может влиять на обычные относительные ссылки. Сохраните эту проверку в матрице шаблона документации: она помогает обнаружить возвращение ошибки после изменения маршрутизации без повторного анализа всего HTML.
Критерии завершения проверки
Буквальный canonical содержит нужный абсолютный HTTPS-адрес; DOM вычисляет тот же URL. Меню, изображения и формы после изменения base продолжают использовать ожидаемые назначения.
- href="article/": Проверить document.baseURI. Зафиксируйте фактический результат и адрес проверенного сценария.
- href="/article/": Слеш не фиксирует домен. Зафиксируйте фактический результат и адрес проверенного сценария.
- Абсолютный HTTPS URL: Предпочтительный вариант. Зафиксируйте фактический результат и адрес проверенного сценария.
- Base меняет скрипт: Найти генератор. Зафиксируйте фактический результат и адрес проверенного сценария.
Для смежных вопросов: HTML валидация: зачем проверять код и как исправить ошибки и Конфликт canonical, sitemap, hreflang и редиректов. Отдельные проверки сайта собраны на странице технического аудита reChecker.