Volver al Centro de conocimiento
Huella digital

Huella getClientRects: coherencia de DOMRect

Interpreta las comprobaciones DOMRect de CreepJS sin confundir geometría vacía, texto fragmentado o informes ausentes con una identidad.

BotBrowser Team

Documentación

Quieres la documentación estructurada de Huella digital?

Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.

La huella de getClientRects examina la geometría de la disposición del navegador, no las cabeceras Client Hints. Un rectángulo puede cambiar porque cambian la caja seleccionada, el fragmento de texto o el contexto de coordenadas. BotBrowser documenta ruido determinista para ClientRects, desactivado por defecto, y una semilla para reproducir métricas de fuentes; esto no garantiza que todas las vías geométricas coincidan ni que CreepJS acepte el resultado. Un informe DOMRect útil separa el objeto medido, la API y la regla concreta antes de atribuir una causa.

Ver el vídeo

Este vídeo en inglés sigue la misma pregunta que el artículo: las cuatro llamadas geométricas de CSSOM View devuelven formas distintas, así que un recuento de fragmentos, un rectángulo envolvente y una selección no pueden leerse como un solo valor. Muestra los tres estados del informe (ausente, lista vacía y rectángulo de dimensión cero), las tres salidas de la reducción envolvente y dos sesiones de consola grabadas en un fixture controlado del mismo origen: dos expresiones nativas escritas a mano, con el panel del fixture imprimiendo la tercera lectura. No muestra recogida en sitios ni un veredicto de terceros, y una diferencia geométrica no identifica un dispositivo, una persona ni un mecanismo de modificación. El audio es inglés.

TL;DR

  • Element.getClientRects() devuelve una lista de fragmentos de caja; getBoundingClientRect() la reduce a un rectángulo, con casos separados para listas vacías y dimensiones nulas. La longitud de la lista y las dimensiones resultantes responden a preguntas distintas.
  • La geometría de Range puede describir fragmentos de texto seleccionado. No equivale a toda la caja de borde de un elemento.
  • La revisión 10aa6724cd33a1015db1574211890518cd04f0cc de CreepJS registra cuatro matrices geométricas y aplica varias comprobaciones específicas, no una prueba universal del dispositivo.
  • Un informe DOMRect ausente, una lista de fragmentos vacía y un rectángulo con ceros son estados diferentes.
  • lied recoge la evaluación de coherencia de esa revisión. No demuestra quién cambió un valor, qué dispositivo lo produjo ni qué decidirá un sitio externo.

Contents

Element y Range ofrecen listas de fragmentos o un rectángulo calculado; informe ausente, lista vacía y rectángulo degenerado son estados distintos.

Cuatro superficies geométricas

CSSOM View define Element.getClientRects() a partir de las cajas CSS del elemento. Un elemento en línea repartido entre varias líneas puede producir varios fragmentos, no un rectángulo continuo. La lista conserva esa separación, incluidos fragmentos de tamaño nulo. Si no hay una caja CSS asociada, devuelve una lista vacía. Por tanto, «el valor ClientRects» resulta incompleto: puede significar una lista, un miembro elegido, una unión derivada o un resumen de varios elementos de prueba.

Element.getBoundingClientRect() reduce la geometría a un rectángulo. La especificación distingue una lista vacía, una lista cuyos rectángulos tienen todos anchura o altura nula y el caso restante de unión. El primer caso devuelve un rectángulo con ceros; el segundo, el primer rectángulo. En el caso restante, la unión incluye rectángulos cuya altura o anchura no es cero: la condición usa OR. Esta última rama no elimina las excepciones anteriores. Un rectángulo en una posición no nula y con altura cero no equivale a la ausencia de fragmentos.

MDN describe el rectángulo del elemento como una caja que incluye relleno y borde, con coordenadas relativas al área visible. Compararlo con width: 100px exige considerar el modelo de caja, no suponer que la anchura declarada coincide con cualquier anchura devuelta. La anchura del contenido y la caja de borde son cantidades diferentes. Un informe que solo guarda una anchura redondeada pierde la API elegida y el modelo de caja.

Range.getClientRects() se refiere a una parte seleccionada del documento. El método envolvente correspondiente reduce su lista, distinguiendo también los casos vacío, de dimensiones nulas y de unión. Una subcadena seleccionada no tiene por qué coincidir con su elemento contenedor: una describe el texto elegido y el otro puede incluir toda la caja. El análisis de medición de texto trata la superficie separada measureText() de Canvas; sus campos TextMetrics no son listas de fragmentos DOMRect.

APIForma devueltaComparación que conserva su significado
Element.getClientRects()DOMRectList de fragmentos de cajaMismo elemento y posiciones de fragmentos
Element.getBoundingClientRect()Un DOMRect obtenido mediante el algoritmo envolventeMismo elemento y contexto del área visible
Range.getClientRects()Lista del intervalo seleccionadoConservar límites de selección y disposición del texto
Range.getBoundingClientRect()Un rectángulo calculado a partir de la listaConservar el intervalo y las ramas vacía y de dimensiones nulas

Las interfaces exponen x, y, width, height, top, right, bottom y left. Serializar estos campos no vuelve equivalentes los objetos de origen. MDN distingue además la interfaz de lista de solo lectura de una matriz JavaScript. Convertir la lista en una matriz cambia el contenedor, no la operación de disposición que produjo sus entradas. Un resumen de esa matriz tampoco explica por sí solo un fragmento diferente.

Qué compara la revisión fijada de CreepJS

El módulo DOMRect público copia los ocho campos en objetos simples y devuelve cuatro matrices: elementClientRects, elementBoundingClientRect, rangeClientRects y rangeBoundingClientRect. En las dos API de listas, la recopilación lee el primer miembro, no todos los rectángulos de una página arbitraria con varias líneas. Esa elección importa: un resumen del grupo no demuestra que se hayan examinado todos los fragmentos de todos los elementos.

El módulo incluye una función que elige el rectángulo preferido. Selecciona entre lista del elemento, rectángulo envolvente del elemento, lista del intervalo y rectángulo envolvente del intervalo según los problemas de API registrados previamente. Esta función es distinta de la recopilación de las cuatro matrices. Afirmar que «CreepJS siempre usa el rectángulo envolvente» eliminaría esas ramas. Sus alternativas tampoco obligan a las cuatro API a devolver rectángulos idénticos para cualquier selección.

La comprobación de movimiento captura el top inicial de un elemento de prueba, aplica una clase de desplazamiento, captura el valor desplazado, retira la clase y vuelve a leer. Compara la restauración respecto de la medida desplazada. No exige que el rectángulo permanezca igual después de modificar la disposición. Fallar la restauración y cambiar la posición inicial son comparaciones diferentes; decir únicamente «cambió la posición» no las distingue.

La comprobación aritmética relaciona bordes opuestos, dimensiones y campos de origen de los rectángulos del elemento. Otra compara los bordes izquierdo y derecho de dos elementos concretos que deberían coincidir. Son predicados distintos: los campos internos pueden ser coherentes aunque los dos elementos difieran. El análisis de grupos de señales de CreepJS explica por qué una evaluación de grupo debe conservar su alcance y no convertirse en una afirmación sobre una persona o todas las API.

Comprobación del códigoQué comparaQué no demuestra por sí solo un fallo
Desplazamiento y restauraciónPosiciones inicial, desplazada y restauradaLa causa de la diferencia
Aritmética del rectánguloRelaciones entre bordes, origen y dimensionesQué capa de software proporcionó el valor
Elementos igualesBordes elegidos de dos elementos concretosIgualdad entre elementos arbitrarios
Elemento giradoExpectativa del código condicionada por motor y DPRUna firma geométrica universal
Elemento fantasmaSi sus ocho campos registrados son ceroQue todo elemento invisible deba tener geometría nula

La rama del elemento girado depende de la clasificación del motor y, en una rama, de devicePixelRatio. Sus valores esperados son supuestos de esa implementación, no una tabla normativa de conformidad. Copiar un resumen conocido no aporta el rectángulo subyacente ni demuestra que se haya medido la disposición original. Solo queda establecido que esta revisión compara su elemento de prueba con una expectativa acotada, no que una diferencia identifique un sistema operativo.

lied también puede comenzar con advertencias anteriores sobre las cuatro API geométricas o String.fromCodePoint, antes de ejecutar estas comprobaciones. Un valor final verdadero no identifica el primer predicado que lo alteró. El módulo captura fallos, registra una prueba fallida y no devuelve resultado; su función de presentación muestra por separado un estado bloqueado cuando falta el informe. «Sin informe» no equivale a una matriz recopilada correctamente que contiene ceros. No se afirma haber ejecutado CreepJS.

Cambios de disposición que alteran la comparación

Las coordenadas relativas al área visible cambian al moverse el contenido respecto de ella. MDN menciona expresamente el desplazamiento al explicar getBoundingClientRect(). Una comparación antes y después de desplazar el documento ha cambiado una entrada, aunque la anchura CSS siga igual. Añadir los desplazamientos permite calcular coordenadas del documento, pero ese valor derivado debe identificarse y no compararse silenciosamente con la coordenada original.

El ajuste de líneas cambia los límites de los fragmentos. Un mismo tramo de texto puede tener distinto DOMRectList.length en una columna estrecha y en una ancha. El rectángulo envolvente resume esos fragmentos y puede incluir espacio no ocupado por ninguna línea. Comparar solo la envolvente puede ocultar el cambio de fragmentación; comparar solo el primer fragmento puede omitir todas las líneas posteriores. Ninguno de los dos casos demuestra una sustitución de fuente.

Las transformaciones CSS afectan a los rectángulos geométricos. Un elemento girado debe compararse con la misma rotación y punto de referencia, no con su tamaño CSS sin giro. El rectángulo envolvente no traza el polígono visible. Por ello, una rama de detección específica del giro necesita su contexto. La anchura medida no puede interpretarse como longitud de un borde girado sin geometría adicional.

Una selección Range añade otra entrada: los nodos o desplazamientos de texto seleccionados. Cambiar de un elemento completo a una subcadena puede alterar legítimamente la lista del intervalo sin cambiar la caja del elemento. El algoritmo CSSOM View también trata de manera distinta el texto y las cajas seleccionadas. Nombrar Range.getClientRects() sin conservar la selección no permite comparar con precisión dos capturas de «la misma página».

La configuración de fuentes pertenece al contexto de disposición, pero un rectángulo diferente no equivale a consultar un nombre de fuente. Disponibilidad de fuentes, sustitución, contenido, anchura del contenedor y estilos pueden influir en el elemento elegido. La documentación de medición de fuentes describe controles de ClientRects, no un DOMRect de referencia para todo texto, selección y disposición. La semilla aporta reproducibilidad al ruido documentado, no a todas las causas de variación de la página.

La comprobación del elemento fantasma debe seguir vinculada a ese elemento. «No visible para una persona» abarca varios estados de representación y no define un único modelo de caja CSS. Un elemento fuera de pantalla puede participar en la disposición; otro sin caja asociada sigue una vía diferente. Generalizar esa prueba a cualquier elemento invisible convertiría una condición concreta en una afirmación más amplia sin fundamento.

Matriz de estados de los informes DOMRect

La primera decisión consiste en saber si se obtuvo geometría. Una excepción del recopilador, una lista vacía y un rectángulo de tamaño nulo requieren estados distintos. Sustituir cualquier fallo por un rectángulo de ceros destruye esa diferencia y puede hacer parecer que una comprobación posterior examinó datos nunca recopilados. Un null elegido por la aplicación tampoco es un resultado nativo DOMRectList.

Estado observadoInterpretación acotadaEntrada de comparación siguiente
Sin informe del recopiladorFalta el informe; la causa no está establecidaFase de captura y categoría de error disponible
Lista con length === 0La llamada no devolvió fragmentosCaja asociada o contexto de selección
Rectángulo de anchura o altura nulaHay geometría con una dimensión degeneradaAPI, posición y otra dimensión
Cambia la longitud de la listaDifiere la estructura de fragmentosMismo texto, anchura, selección y momento de disposición
Falla un predicado aritméticoLos campos no cumplen esa comparaciónCampos originales y nombre del predicado
Solo cambia el resumen del grupoAlguna entrada serializada difiereMatriz, elemento y campos antes de atribuir causas

Son casos derivados de las fuentes, no resultados medidos. Por ejemplo, una lista hipotéticamente vacía seguida de un rectángulo envolvente de ceros puede concordar con la reducción especificada. No demuestra que un detector haya encontrado una modificación. Un informe que afirma haber leído la lista pero no guarda su longitud tampoco distingue ese caso de un valor ausente insertado por el serializador.

Otro ejemplo hipotético es un tramo multilínea con más fragmentos al estrecharse el contenedor. La conclusión útil es que cambió una entrada de disposición y la fragmentación. No se predicen dimensiones concretas ni se identifica un dispositivo. En un tercer caso, el elemento permanece fijo y cambia la subcadena seleccionada: el intervalo cambia mientras la comparación del elemento puede mantenerse estable. Cada ejemplo conserva la pregunta de la API.

Un cuarto caso es una evaluación CreepJS sin motivo individual. lied no distingue advertencias heredadas de geometría o String.fromCodePoint, fallo de restauración, fallo aritmético o expectativa de un elemento de prueba. El motivo diagnóstico concreto informa más que una causa supuesta asociada al booleano. Esto no exige recopilar todos los rectángulos de una página ni exportar una huella reutilizable a terceros.

Registro de comparación acotado

Un registro mínimo puede responder a la pregunta sin conservar todo el texto ni cada valor geométrico. Incluye api, un identificador no sensible del elemento de prueba, tipo de selección, longitud de lista cuando corresponda, estado de recopilación y regla concreta. Añade la revisión del código para interpretar CreepJS. Una regla no es «estándar» solo porque lo sea el método. El algoritmo de la API y las expectativas del detector son capas diferentes.

CampoPor qué afecta a la interpretación
apiSepara Element/Range y lista/rectángulo
selectionTypeDistingue elemento y subcadena
fragmentCountConserva estados vacío y fragmentado
coordinateSpaceIdentifica coordenadas visibles o una conversión derivada
layoutContextIdentifica anchura, desplazamiento y rotación relevantes
collectionStateSepara captura obtenida, vacía y fallida
rule y sourceRevisionVinculan la evaluación al predicado y código reales

Estos nombres constituyen un esquema propuesto para asistencia, no claves de salida de CreepJS salvo las matrices nombradas expresamente. No debe registrarse fragmentCount: 0 si la recopilación falló antes de obtener una lista. Tampoco debe sustituirse una evaluación ausente por una cadena vacía: parecería una comparación ejecutada sin hallazgos. Minimizar datos y representar correctamente los estados contribuyen al mismo diagnóstico.

El control documentado --bot-noise-client-rects=true activa ruido determinista y está desactivado por defecto. --bot-noise-seed permite reproducir las métricas de fuentes según la documentación. Ninguna afirmación demuestra igual cobertura de Element y Range, conservación de todas las expectativas aritméticas de un detector, anonimato o aceptación por un servicio. Eso requiere pruebas propias. --bot-noise-text-rects=true es otro control y no sustituye silenciosamente al de ClientRects.

La secuencia práctica es identificar la API y el estado, comprobar si coinciden selección y disposición y después examinar el predicado nombrado. Sin esas entradas, solo queda una diferencia geométrica sin explicar. Atribuir sistema operativo, dispositivo o mecanismo excedería el registro. La comprobación mínima útil reproduce el elemento concreto, sin ampliar la recopilación a señales de identidad ajenas.

Preguntas frecuentes sobre ClientRects

¿ClientRects significa Client Hints?

No. getClientRects() es un método geométrico. Client Hints comunica información del navegador mediante otro mecanismo. Una cabecera no demuestra la disposición de un elemento y un informe DOMRect no establece qué cabeceras se enviaron.

¿Un resumen distinto identifica el rectángulo cambiado?

No. Resume entradas serializadas. Sin la matriz, el elemento y los campos originales, no localiza la diferencia. Justifica examinar el grupo, pero no determina por sí solo la entrada cambiada ni su causa.

¿Element y Range deben coincidir siempre?

No. La caja de un elemento y un intervalo seleccionado pueden abarcar contenido diferente. Una relación válida para un elemento de prueba no garantiza igualdad para selecciones arbitrarias, texto multilínea o cajas giradas.

¿Un rectángulo de ceros demuestra un bloqueo?

No. La reducción de una lista vacía puede devolverlo y una caja degenerada es otro estado. La presentación de informe ausente de CreepJS es independiente. Hay que conservar si la llamada produjo lista, rectángulo o ningún informe.

¿La expectativa del elemento girado es un estándar web?

No. El código fijado aplica una rama condicionada por motor y DPR. CSSOM View define métodos, no los resúmenes esperados del detector. Una revisión posterior puede cambiar esa rama sin cambiar el nombre de la API.

¿Una semilla garantiza igualdad en todas partes?

No. La semilla documentada afecta al ruido reproducible. Texto, anchura, selección, transformaciones y coordenadas distintos siguen cambiando la pregunta geométrica. La configuración no demuestra equivalencia entre dispositivos ni un resultado del detector.

Fuentes

Conclusión práctica

Un informe útil de huella getClientRects identifica una API, un objeto seleccionado y una comparación concreta. Conserva los estados vacío, degenerado y fallido y separa las reglas de CreepJS de la geometría normativa. Si solo queda un resumen o booleano, la causa sigue sin resolver. Comprueba el contexto de API o del elemento antes de cambiar ajustes o atribuir una identidad al dispositivo.

#fingerprinting#fuentes#privacidad

Este artículo forma parte de la guía: ¿Qué es la huella digital del navegador?

Lleva BotBrowser de la investigación a producción

Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.