Riepilogo
Se il tuo sito Discourse appare come HTML semplice e non stilizzato quando viene aperto tramite un link nell’app di Facebook su iPhone — senza CSS, senza JavaScript, senza funzionalità — la causa è il rilevamento errato del crawler da parte di Discourse, che identifica erroneamente il browser integrato di Facebook come un bot.
La soluzione consiste in una modifica di una riga tramite la console Rails.
Il sintomo
Gli utenti che cliccano sui link del tuo sito Discourse dall’app di Facebook su iPhone visualizzano una pagina HTML semplificata e non stilizzata, essenzialmente il layout crawler/noscript. Nessun JavaScript viene eseguito, quindi funzionalità come griglie di immagini, lightbox e player multimediali non funzionano. Gli stessi link funzionano correttamente in Safari, Chrome e nel browser integrato di Facebook su Android e iPad.
La causa
Il browser integrato di Facebook su iPhone si identifica con una stringa user agent contenente la parola facebook, ad esempio:
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
Il rilevamento del crawler di Discourse (CrawlerDetection) confronta gli user agent con l’impostazione del sito crawler_user_agents, il cui valore predefinito include facebook:
rss|bot|spider|crawler|facebook|archive|wayback|ping|...
Ciò fa sì che Discourse serva al browser integrato di Facebook il layout statico del crawler invece dell’applicazione Ember completa, anche se si tratta di un vero browser utilizzato da una persona reale.
Puoi confermare che questo sta accadendo controllando il log di accesso di nginx per le richieste provenienti da questo browser e notando che la dimensione del payload di risposta è drasticamente inferiore alla norma (tipicamente ~5KB contro ~35KB per una pagina di argomento completa).
La soluzione
Aggiungi MetaIAB all’impostazione del sito crawler_check_bypass_agents. Questa impostazione è specificamente progettata per esentare gli user agent dal trattamento da crawler anche quando corrispondono all’elenco dei crawler.
Nota: crawler_check_bypass_agents è un’impostazione del sito nascosta e non appare nell’interfaccia utente amministrativa standard. È richiesta la console Rails.
Tramite la console Rails
SiteSetting.crawler_check_bypass_agents = "MetaIAB"
Se l’impostazione ha già un valore (ad esempio cubot), aggiungi con un separatore pipe:
SiteSetting.crawler_check_bypass_agents = "cubot|MetaIAB"
La modifica ha effetto immediato: non è necessario riavviare.
Perché funziona
Il metodo CrawlerDetection.crawler? utilizza tre impostazioni in combinazione:
non_crawler_user_agents— se l’UA corrisponde a questo elenco, potrebbe essere un vero browsercrawler_user_agents— se corrisponde anche a questo elenco, viene trattato come un crawlercrawler_check_bypass_agents— se corrisponde a questo elenco, viene esentato dal trattamento da crawler indipendentemente
L’UA del browser integrato di Facebook contiene Safari, che corrisponde a non_crawler_user_agents. Contiene anche facebook, che corrisponde a crawler_user_agents. Aggiungere MetaIAB — una stringa unica per l’UA del browser integrato di Facebook — a crawler_check_bypass_agents fa sì che Discourse serva l’applicazione completa.
Perché Android e iPad non sono interessati
- Android: Il browser integrato di Facebook su Android invia un user agent diverso che non contiene
facebook, quindi supera il rilevamento del crawler senza problemi. - iPad: Il browser integrato di Facebook su iPad attiva anche il layout del crawler, ma poiché l’iPad riporta una larghezza
window.innerWidthampia (~1180px), Discourse serve il layout desktop che risulta adeguatamente renderizzato. La visualizzazione stretta dell’iPhone (~414px) attiva il layout mobile, che in modalità crawler è completamente non funzionante.
Nota aggiuntiva: inondazione da meta-webindexer
Separatamente, l’indicizzatore web di Facebook (meta-webindexer/1.1) potrebbe inviare un volume molto elevato di richieste al tuo sito — potenzialmente migliaia all’ora — tutte rivolte alla homepage. A differenza di meta-externalagent (che gestisce le anteprime dei link OG e dovrebbe rimanere sbloccato), meta-webindexer sembra non avere alcuno scopo utile per la maggior parte delle installazioni di Discourse.
Se osservi questo traffico nei tuoi log, puoi bloccarlo a livello di nginx aggiungendolo alla configurazione del blocco bot:
"~*meta-webindexer" 1;
meta-externalagent deve rimanere consentito, poiché è responsabile dell’estrazione dei metadati OG quando i link vengono condivisi su Facebook.