Отпечаток getClientRects: согласованность DOMRect
Проверки DOMRect в CreepJS: как различать пустую геометрию, фрагменты текста и отсутствие отчёта, не приписывая им идентичность устройства.
BotBrowser Team
Нужна структурированная документация по теме Отпечатки?
Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.
Отпечаток getClientRects связан с геометрией компоновки браузера, а не с заголовками Client Hints. Прямоугольник может измениться из-за выбранного блока, фрагмента текста или системы координат. BotBrowser документирует детерминированный шум ClientRects, по умолчанию выключенный, и начальное значение для воспроизводимых метрик шрифтов. Это не гарантирует согласованность всех геометрических путей или принятие результата CreepJS. Полезный отчёт DOMRect разделяет измеряемый объект, API и конкретное условие проверки до поиска причины.
Смотреть видео
Это видео на английском следует тому же вопросу, что и статья: четыре геометрических вызова CSSOM View возвращают разные формы, поэтому число фрагментов, охватывающий прямоугольник и выделение нельзя читать как одно значение. В нём показаны три состояния отчёта (отсутствует, пустой список и прямоугольник нулевого размера), три ветви редукции охватывающего прямоугольника и две записанные сессии консоли на контролируемой фикстуре того же источника: две нативные выражения вводятся вручную, третье измерение выводит панель фикстуры. Видео не показывает сбор данных сайтом и не даёт сторонней оценки; геометрическое различие не определяет устройство, человека или способ модификации. Аудио на английском.
TL;DR
Element.getClientRects()возвращает список фрагментов блока, аgetBoundingClientRect()сводит его к одному прямоугольнику с отдельными случаями пустого списка и нулевых размеров. Длина списка и размеры отвечают на разные вопросы.- Геометрия
Rangeможет описывать фрагменты выделенного текста, а не весь блок элемента с границей. - Ревизия CreepJS
10aa6724cd33a1015db1574211890518cd04f0ccсохраняет четыре массива и выполняет проверки конкретных тестовых элементов, а не универсальный тест устройства. - Отсутствующий отчёт, пустой список фрагментов и прямоугольник с нулевыми полями являются разными состояниями.
liedотражает оценку согласованности этой ревизии. Он не устанавливает источник изменения, устройство или решение внешнего сайта.
Contents
- Смотреть видео
- Четыре геометрических интерфейса
- Что сравнивает выбранная ревизия CreepJS
- Изменения компоновки при сравнении
- Матрица состояний отчёта DOMRect
- Ограниченная запись сравнения
- Вопросы о сигналах ClientRects
- Практический вывод
Четыре геометрических интерфейса
CSSOM View определяет Element.getClientRects() через CSS-блоки элемента. Строчный элемент, занимающий несколько строк, может дать несколько фрагментов вместо одного непрерывного прямоугольника. Список сохраняет различия между ними, включая фрагменты нулевого размера. Если связанного CSS-блока нет, список пуст. Поэтому «значение ClientRects» неоднозначно: это может быть список, выбранный элемент списка, производное объединение или сводный отпечаток нескольких тестовых объектов.
Element.getBoundingClientRect() сводит геометрию к одному прямоугольнику. Спецификация различает пустой список, список, где каждый прямоугольник имеет нулевую ширину или высоту, и оставшийся случай объединения. В первом случае возвращается прямоугольник с нулями, во втором - первый прямоугольник списка. Иначе объединяются прямоугольники, у которых высота или ширина не равна нулю: используется условие OR. Последняя ветвь не отменяет предыдущие исключения. Нулевая высота при ненулевой позиции не равнозначна отсутствию фрагментов.
MDN описывает прямоугольник элемента с внутренними отступами и границей, в координатах области просмотра. Сравнивая его с width: 100px, необходимо учитывать модель блока, а не требовать равенства объявленной и любой возвращённой ширины. Ширина содержимого и блок с границей - разные величины. Запись только округлённой ширины теряет выбор API и модель блока.
Range.getClientRects() относится к выделенной части документа. Соответствующий метод общих границ сводит список, также различая пустой список, нулевые размеры и объединение. Выделенная подстрока не обязана совпадать по границам с содержащим её элементом: одна описывает выбранный текст, другой может включать весь блок. Разбор измерения текста рассматривает отдельную поверхность Canvas measureText(); поля TextMetrics не являются списками фрагментов DOMRect.
| API | Форма результата | Корректный контекст сравнения |
|---|---|---|
Element.getClientRects() | DOMRectList фрагментов блока | Тот же элемент и позиции фрагментов |
Element.getBoundingClientRect() | Один DOMRect по алгоритму общих границ | Тот же элемент и область просмотра |
Range.getClientRects() | Список для выделенного диапазона | Те же границы выделения и компоновка текста |
Range.getBoundingClientRect() | Прямоугольник по свёртке списка диапазона | Сохранить выделение и ветви пустых и нулевых результатов |
Интерфейсы содержат x, y, width, height, top, right, bottom и left. Сериализация этих полей не делает исходные объекты равнозначными. MDN также отличает интерфейс списка только для чтения от массива JavaScript. Преобразование списка в массив меняет контейнер, а не операцию компоновки, создавшую записи. Сводный отпечаток массива сам по себе не объясняет изменение фрагмента.
Что сравнивает выбранная ревизия CreepJS
Открытый модуль DOMRect копирует восемь полей в обычные объекты и возвращает четыре массива: elementClientRects, elementBoundingClientRect, rangeClientRects и rangeBoundingClientRect. При сборе через два списочных API выбирается первый элемент списка, а не каждый прямоугольник произвольной многострочной страницы. Это существенно: сводное значение группы не доказывает исследование всех фрагментов всех элементов.
В модуле также есть функция выбора предпочтительного прямоугольника. Она выбирает список элемента, общие границы элемента, список диапазона или общие границы диапазона в зависимости от ранее отмеченных проблем API. Эта функция отделена от сбора четырёх массивов. Фраза «CreepJS всегда использует общие границы» скрыла бы ветвление. Альтернативы функции также не означают, что четыре API обязаны давать одинаковую геометрию при любом выделении.
Проверка движения сохраняет исходный top, добавляет класс смещения, читает смещённое значение, удаляет класс и читает ещё раз. Сравнивается восстановление относительно смещённого измерения. Это не требование неизменности прямоугольника после изменения компоновки. Ошибка восстановления и другая исходная позиция - разные сравнения; формулировка «позиция изменилась» их не различает.
Арифметическая проверка сопоставляет противоположные границы, размеры и поля начала координат прямоугольников элемента. Другая проверка сравнивает левую и правую границы двух конкретных объектов, рассчитанных на совпадение. Это разные предикаты: внутренняя арифметика может сходиться при различии двух объектов. Разбор групп CreepJS объясняет, почему оценка группы должна сохранять свой охват, а не превращаться в утверждение о человеке или всех API.
| Проверка исходного кода | Что сравнивается | Чего один сбой не доказывает |
|---|---|---|
| Смещение и восстановление | Исходная, смещённая и восстановленная позиции | Причину различия |
| Арифметика прямоугольника | Связи границ, начала координат и размеров | Какой слой программы предоставил значение |
| Одинаковые объекты | Выбранные границы двух конкретных элементов | Равенство произвольных элементов страницы |
| Поворот | Ожидание кода с условиями по движку и DPR | Универсальную геометрическую подпись |
| Призрачный элемент | Равны ли нулю все восемь полей | Что любой невидимый элемент обязан иметь нулевую геометрию |
Ветка поворота зависит от классификации движка, а в одной ветви - от devicePixelRatio. Ожидаемые значения являются предположениями реализации, а не нормативной таблицей соответствия. Копирование известного сводного значения не даёт исходный прямоугольник и не доказывает измерение оригинальной компоновки. Обоснованный вывод ограничен сравнением конкретной ревизии с её ожиданием; несоответствие не устанавливает операционную систему.
lied может изначально включать ранее зарегистрированные замечания к четырём геометрическим API или String.fromCodePoint, ещё до локальных проверок. Итоговое true не показывает первый повлиявший предикат. Модуль перехватывает ошибки, отмечает неуспешную проверку и не возвращает результат; отображение отдельно показывает блокировку при отсутствии отчёта. Этот путь отличается от успешно собранного массива с нулями. Запуск CreepJS здесь не заявляется.
Изменения компоновки при сравнении
Координаты области просмотра меняются при движении содержимого относительно неё. MDN прямо упоминает прокрутку в описании getBoundingClientRect(). Сравнение до и после прокрутки уже меняет входные условия, даже при прежней ширине CSS. Добавление смещения позволяет вычислять координаты документа, но производную величину следует явно обозначить, а не незаметно сравнивать с исходной координатой области просмотра.
Перенос строк меняет границы фрагментов. Один текстовый элемент может иметь разный DOMRectList.length в узком и широком столбце. Общий прямоугольник обобщает фрагменты и может включать пространство, не занятое ни одной строкой. Проверка только общих границ скрывает различия разбиения; проверка только первого фрагмента игнорирует последующие строки. Ни один вариант не доказывает замену шрифта.
CSS-преобразования влияют на геометрические прямоугольники. Повёрнутый объект нужно сравнивать при том же повороте и опорной точке, а не с размерами CSS без поворота. Общие границы не являются контуром видимого многоугольника. Поэтому проверке повёрнутого элемента нужен собственный контекст. Без дополнительных вычислений измеренная ширина не равна длине повёрнутой стороны.
Range добавляет входные данные: выбранные узлы или смещения текста. Переход от всего элемента к подстроке может закономерно изменить список диапазона при неизменном блоке элемента. Алгоритм CSSOM View также различает выбранный текст и блоки. Если отчёт называет Range.getClientRects(), но не сохраняет выделение, точное сравнение двух снимков «той же страницы» невозможно.
Шрифты входят в контекст компоновки, но изменившийся прямоугольник не является поиском имени шрифта. Доступность, подстановка, текст, ширина контейнера и стили могут влиять на выбранный объект. Документация по измерению шрифтов описывает настройки ClientRects, но не эталон DOMRect для любого текста, выделения и компоновки. Начальное значение обеспечивает воспроизводимость документированного шума, а не всех изменений страницы.
Проверка призрачного элемента тоже привязана к своему объекту. «Невидим для человека» охватывает несколько состояний отображения и не задаёт единую модель CSS-блока. Элемент за пределами экрана может участвовать в компоновке; отсутствие связанного блока ведёт по другой ветви API. Обобщение проверки на любую невидимость заменило бы конкретное условие более широким неподтверждённым утверждением.
Матрица состояний отчёта DOMRect
Сначала нужно установить, получена ли геометрия. Исключение сборщика, пустой список и прямоугольник нулевого размера требуют разных записей. Подстановка нулевого прямоугольника при любой ошибке стирает различие и создаёт видимость проверки данных, которых не собирали. Выбранный приложением null также не является собственным результатом DOMRectList.
| Наблюдаемое состояние | Ограниченный вывод | Следующие входные данные |
|---|---|---|
| Отчёт не возвращён | Отчёт отсутствует, причина неизвестна | Этап сбора и доступная категория ошибки |
Список с length === 0 | Вызов не вернул фрагменты | Наличие блока или контекст выделения |
| Нулевая ширина или высота | Геометрия есть, одно измерение вырождено | API, позиция и другое измерение |
| Изменена длина списка | Структура фрагментов отличается | Тот же текст, ширина, выделение и момент компоновки |
| Не сходится арифметика | Поля не проходят конкретный предикат | Исходные поля и имя условия |
| Меняется лишь сводное значение группы | Где-то различаются сериализованные данные | Массив, объект и поля до поиска причины |
Это случаи, выведенные из источников, а не результаты измерений браузера. Например, гипотетический пустой список и следующий за ним нулевой прямоугольник могут соответствовать алгоритму свёртки. Это не доказывает обнаружение модификации. Отчёт, утверждающий успешное чтение без сохранения длины списка, также не отличает этот случай от отсутствующего значения, добавленного сериализатором.
Второй гипотетический пример - больше фрагментов многострочного текста при сужении контейнера. Полезный вывод состоит в изменении входных условий и разбиения. Конкретная ширина или высота не предсказывается, устройство не определяется. В третьем примере элемент неизменен, но выделена другая подстрока: результат Range меняется, тогда как сравнение элемента может остаться прежним. Каждый пример сохраняет вопрос, заданный API.
Четвёртый случай - оценка CreepJS без отдельной причины. По lied нельзя выбрать между унаследованными замечаниями к геометрии или String.fromCodePoint, ошибкой восстановления, арифметикой или ожиданием конкретного объекта. Именованная диагностическая причина полезнее догадки по одному булеву значению. Для этого не требуется собирать все прямоугольники страницы или передавать третьей стороне повторно используемый отпечаток.
Ограниченная запись сравнения
Минимальная запись отвечает на диагностический вопрос без всего текста страницы и полного набора геометрии. Сохраняются api, нечувствительный идентификатор тестового объекта, тип выделения, длина списка, если применима, состояние сбора и именованная проверка. Для CreepJS добавляется ревизия кода. Нормативность метода измерения не делает сам предикат стандартом: алгоритм API и ожидания детектора - разные уровни.
| Поле | Значение для интерпретации |
|---|---|
api | Разделяет Element/Range и список/общие границы |
selectionType | Отличает элемент от подстроки |
fragmentCount | Сохраняет пустое и фрагментированное состояния |
coordinateSpace | Указывает координаты области просмотра или производное преобразование |
layoutContext | Указывает ширину, прокрутку и повороты |
collectionState | Разделяет полученный, пустой и неуспешный результат |
rule и sourceRevision | Привязывают оценку к реальному предикату и коду |
Эти имена являются предложенной схемой записи для поддержки, а не ключами вывода CreepJS, кроме явно названных массивов. Нельзя записывать fragmentCount: 0, если сбор оборвался до получения списка. Пустая строка вместо отсутствующей оценки тоже создаст впечатление выполненного сравнения без замечаний. Минимизация данных и точное представление состояний помогают одной диагностической задаче.
Документированный параметр --bot-noise-client-rects=true включает детерминированный шум и по умолчанию выключен. --bot-noise-seed описан для воспроизводимых метрик шрифтов. Эти сведения не доказывают одинаковый охват Element и Range, сохранение всех арифметических ожиданий детектора, анонимность или принятие сервисом. Для таких результатов нужны собственные доказательства. --bot-noise-text-rects=true - отдельный параметр, не неявная замена настройки ClientRects.
Практическая последовательность: определить API и состояние, сопоставить выделение и компоновку, затем проверить названный предикат. Если входных данных нет, остаётся только необъяснённое геометрическое различие. Назначать ему ОС, модель устройства или механизм изменения нельзя. Минимальный полезный следующий шаг - воспроизвести конкретный тестовый объект, а не расширять сбор посторонних сигналов идентичности.
Вопросы о сигналах ClientRects
ClientRects и Client Hints - одно и то же?
Нет. getClientRects() измеряет геометрию. Client Hints передаёт сведения браузера другим механизмом. Заголовок не доказывает расположение элемента, а отчёт DOMRect не устанавливает отправленные заголовки.
Изменившийся отпечаток указывает конкретный прямоугольник?
Нет. Он сводит сериализованные входные данные. Без массива, объекта и исходных полей он не локализует отличие. Он обосновывает просмотр группы, но не определяет изменившийся ввод или его причину.
Геометрия Element и Range всегда должна совпадать?
Нет. Блок элемента и выделенный текст могут охватывать разное содержимое. Соответствие в одном тестовом объекте не гарантирует равенство произвольных выделений, многострочного текста или повёрнутых блоков.
Нулевой прямоугольник означает блокировку сбора?
Нет. Его может вернуть алгоритм пустого списка; вырожденные блоки - отдельный случай. Отображение отсутствующего отчёта CreepJS тоже отдельно. Сначала нужно сохранить, получен ли список, прямоугольник или никакого отчёта.
Ожидание повёрнутого объекта является веб-стандартом?
Нет. Зафиксированный код использует ветвь с условиями по движку и DPR. CSSOM View определяет методы, а не ожидаемые отпечатки детектора. Следующая ревизия может изменить условие без смены имени API.
Начальное значение гарантирует равенство везде?
Нет. Документированная настройка относится к воспроизводимому шуму. Другой текст, ширина, выделение, преобразования или координаты меняют сам геометрический вопрос. Одна настройка не доказывает равенство устройств или результат детектора.
Источники
- CSSOM View: геометрия элементов и диапазонов
- MDN: Element.getClientRects()
- MDN: Element.getBoundingClientRect()
- MDN: Range.getClientRects()
- MDN: Range.getBoundingClientRect()
- MDN: DOMRect
- MDN: DOMRectList
- CreepJS: модуль DOMRect выбранной ревизии
- BotBrowser: настройки измерения шрифтов
Практический вывод
Полезный отчёт об отпечатке getClientRects указывает API, выбранный объект и точное сравнение. Сохраняются пустые, вырожденные и неуспешные состояния; правила CreepJS отделяются от нормативной геометрии. Если остались только сводный отпечаток или булево значение, причина неизвестна. Проверить контекст API и объекта следует до изменения настроек или приписывания устройству идентичности.
Эта статья входит в руководство: Что такое отпечаток браузера?
Похожие статьи
Fingerprinting измерения текста: субпиксельное отслеживание
ОтпечаткиКак читать сигналы отпечатка браузера
ОтпечаткиАудиоотчёт CreepJS: рендеринг и пропуски
ОтпечаткиМетрики эмодзи CreepJS: множества и суммы
ОтпечаткиClient Hints Fingerprinting: HTTP-заголовки и идентичность
ОтпечаткиCanvas-отпечаток: пустой экспорт и ошибки
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.