Solución: Discourse se muestra como HTML sin estilo en el navegador integrado de Facebook en iPhone

Resumen

Si tu sitio Discourse se ve como HTML plano y sin estilo cuando se accede a él mediante un enlace en la aplicación de Facebook en iPhone —sin CSS, sin JavaScript, sin funcionalidad— la causa es que la detección de rastreadores de Discourse identifica incorrectamente al navegador integrado de Facebook como un bot.

La solución es un cambio de una sola línea a través de la consola de Rails.


El síntoma

Los usuarios que hacen clic en enlaces a tu sitio Discourse desde la aplicación de Facebook en iPhone ven una página HTML simplificada y sin estilo, esencialmente el diseño de rastreador/noscript. No se ejecuta JavaScript, por lo que funciones como cuadrículas de imágenes, lightboxes y reproductores de medios no funcionan. Los mismos enlaces funcionan correctamente en Safari, Chrome y en el navegador integrado de Facebook en Android e iPad.


La causa

El navegador integrado de Facebook en iPhone se identifica con una cadena de agente de usuario que contiene la palabra facebook, por ejemplo:

Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 
(KHTML, like Gecko) Mobile/23D8133 Safari/604.1 MetaIAB Facebook

La detección de rastreadores de Discourse (CrawlerDetection) verifica los agentes de usuario contra la configuración del sitio crawler_user_agents, cuyo valor predeterminado incluye facebook:

rss|bot|spider|crawler|facebook|archive|wayback|ping|...

Esto hace que Discourse sirva al navegador integrado de Facebook el diseño estático de rastreador en lugar de la aplicación Ember completa, aunque se trate de un navegador real utilizado por una persona real.

Puedes confirmar que esto está ocurriendo revisando tu registro de acceso de nginx para las solicitudes de este navegador y notando que el tamaño de la carga de respuesta es dramáticamente más pequeño de lo normal (típicamente ~5KB frente a ~35KB para una página de tema completa).


La solución

Agrega MetaIAB a la configuración del sitio crawler_check_bypass_agents. Esta configuración está diseñada específicamente para eximir a los agentes de usuario del tratamiento de rastreadores, incluso si coinciden con la lista de rastreadores.

Nota: crawler_check_bypass_agents es una configuración del sitio oculta y no aparece en la interfaz de administración estándar. Se requiere la consola de Rails.

A través de la consola de Rails

SiteSetting.crawler_check_bypass_agents = "MetaIAB"

Si la configuración ya tiene un valor (por ejemplo, cubot), agrégalo con un separador de barra vertical:

SiteSetting.crawler_check_bypass_agents = "cubot|MetaIAB"

El cambio surte efecto inmediatamente; no se requiere reinicio.


Por qué funciona esto

El método CrawlerDetection.crawler? utiliza tres configuraciones en combinación:

  1. non_crawler_user_agents — si el UA coincide con esta lista, podría ser un navegador real.
  2. crawler_user_agents — si también coincide con esta lista, se trata como un rastreador.
  3. crawler_check_bypass_agents — si coincide con esta lista, se exime del tratamiento de rastreadores independientemente.

El UA del navegador integrado de Facebook contiene Safari, que coincide con non_crawler_user_agents. También contiene facebook, que coincide con crawler_user_agents. Agregar MetaIAB —una cadena única del UA del navegador integrado de Facebook— a crawler_check_bypass_agents hace que Discourse le sirva la aplicación completa.


Por qué Android e iPad no se ven afectados

  • Android: El navegador integrado de Facebook en Android envía un agente de usuario diferente que no contiene facebook, por lo que pasa la detección de rastreadores sin problemas.
  • iPad: El navegador integrado de Facebook en iPad también activa el diseño de rastreador, pero como el iPad reporta un ancho de ventana window.innerWidth amplio (~1180px), Discourse sirve el diseño de escritorio, que resulta renderizarse adecuadamente. La vista estrecha del iPhone (~414px) activa el diseño móvil, que en modo rastreador es completamente no funcional.

Nota adicional: inundación de meta-webindexer

Por separado, el indexador web de Facebook (meta-webindexer/1.1) puede enviar un volumen muy alto de solicitudes a tu sitio, potencialmente miles por hora, todas dirigidas a la página de inicio. A diferencia de meta-externalagent (que maneja las vistas previas de enlaces OG y debe permanecer sin bloquear), meta-webindexer parece no tener ningún propósito útil para la mayoría de las instalaciones de Discourse.

Si observas este tráfico en tus registros, puedes bloquearlo a nivel de nginx agregándolo a tu configuración de bloqueo de bots:

"~*meta-webindexer" 1;

meta-externalagent debe permanecer permitido, ya que es responsable de extraer metadatos OG cuando se comparten enlaces en Facebook.

2 Me gusta

Gracias @shortmort37. He creado una PR para cambiar el valor predeterminado en el núcleo e incluir MetaIAB:

5 Me gusta