ملخص
إذا ظهر موقع Discourse الخاص بك كـ HTML عادي غير منسق عند الوصول إليه عبر رابط في تطبيق Facebook على iPhone — بدون CSS، وبدون JavaScript، وبدون وظائف — فإن السبب هو أن كشف الزحف (crawler detection) في Discourse يحدد بشكل خاطئ متصفح Facebook المدمج على أنه روبوت.
الحل هو تغيير من سطر واحد عبر وحدة تحكم Rails.
العرض
عندما ينقر المستخدمون على روابط لموقع Discourse الخاص بك من تطبيق Facebook على iPhone، يرون صفحة HTML مبسطة غير منسقة — وهي في الأساس تخطيط الزحف/noscript. لا يتم تشغيل أي JavaScript، لذا لا تعمل ميزات مثل شبكات الصور، والصناديق الخفيفة (lightboxes)، ومشغلات الوسائط. تعمل نفس الروابط بشكل صحيح في Safari وChrome ومتصفح Facebook المدمج على Android وiPad.
السبب
يحدد متصفح Facebook المدمج على iPhone نفسه بسلسلة وكيل مستخدم (user agent string) تحتوي على كلمة facebook، على سبيل المثال:
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
يتحقق كشف الزحف في Discourse (CrawlerDetection) من وكلاء المستخدمين مقابل إعداد الموقع crawler_user_agents، حيث تتضمن القيمة الافتراضية facebook:
rss|bot|spider|crawler|facebook|archive|wayback|ping|...
يتسبب هذا في تقديم Discourse لمتصفح Facebook المدمج تخطيط الزحف الثابت بدلاً من تطبيق Ember الكامل — رغم أنه متصفح حقيقي يستخدمه شخص حقيقي.
يمكنك تأكيد حدوث ذلك من خلال التحقق من سجل الوصول في nginx لطلبات من هذا المتصفح وملاحظة أن حجم استجابة الحمولة أصغر بكثير من المعتاد (عادةً حوالي 5 كيلوبايت مقابل 35 كيلوبايت لصفحة موضوع كاملة).
الحل
أضف MetaIAB إلى إعداد الموقع crawler_check_bypass_agents. تم تصميم هذا الإعداد خصيصًا لإعفاء وكلاء المستخدمين من معاملة الزحف حتى لو تطابقوا مع قائمة الزحف.
ملاحظة: crawler_check_bypass_agents هو إعداد موقع مخفي ولا يظهر في واجهة المستخدم الإدارية القياسية. يتطلب الأمر وحدة تحكم Rails.
عبر وحدة تحكم Rails
SiteSetting.crawler_check_bypass_agents = "MetaIAB"
إذا كان الإعداد يحتوي بالفعل على قيمة (مثل cubot)، فقم بإضافتها باستخدام فاصل الأنبوب:
SiteSetting.crawler_check_bypass_agents = "cubot|MetaIAB"
يتم تطبيق التغيير فورًا — لا حاجة لإعادة التشغيل.
لماذا يعمل هذا
تستخدم طريقة CrawlerDetection.crawler? ثلاثة إعدادات معًا:
non_crawler_user_agents— إذا تطابق وكيل المستخدم (UA) مع هذه القائمة، فقد يكون متصفحًا حقيقيًاcrawler_user_agents— إذا تطابق أيضًا مع هذه القائمة، يتم معاملته كزاحفcrawler_check_bypass_agents— إذا تطابق مع هذه القائمة، يتم إعفاؤه من معاملة الزحف بغض النظر
يحتوي وكيل مستخدم متصفح Facebook المدمج على Safari، الذي يتطابق مع non_crawler_user_agents. كما يحتوي على facebook، الذي يتطابق مع crawler_user_agents. يؤدي إضافة MetaIAB — وهي سلسلة فريدة لوكيل مستخدم متصفح Facebook المدمج — إلى crawler_check_bypass_agents إلى جعل Discourse يقدم له التطبيق الكامل.
لماذا لا يتأثر Android وiPad
- Android: يرسل متصفح Facebook المدمج على Android وكيل مستخدم مختلف لا يحتوي على
facebook، لذا يجتاز كشف الزحف دون مشكلة. - iPad: يثير متصفح Facebook المدمج على iPad أيضًا تخطيط الزحف، ولكن نظرًا لأن iPad يبلغ عن عرض نافذة واسع (
window.innerWidthحوالي 1180 بكسل)، يقدم Discourse تخطيط سطح المكتب الذي يحدث أن يعمل بشكل كافٍ. بينما يحفز عرض العرض الضيق لـ iPhone (حوالي 414 بكسل) تخطيط الهاتف المحمول، والذي في وضع الزحف غير وظيفي تمامًا.
ملاحظة إضافية: فيض meta-webindexer
بشكل منفصل، قد يرسل فهرس الويب الخاص بـ Facebook (meta-webindexer/1.1) حجمًا مرتفعًا جدًا من الطلبات إلى موقعك — ربما آلاف الطلبات في الساعة — وجميعها تستهدف الصفحة الرئيسية. على عكس meta-externalagent (الذي يعالج معاينات الروابط OG ويجب أن يظل غير محظور)، يبدو أن meta-webindexer لا يخدم أي غرض مفيد لمعظم تركيبات Discourse.
إذا لاحظت هذا الحركة في سجلاتك، فيمكنك حظرها على مستوى nginx بإضافتها إلى تكوين حظر الروبوتات الخاص بك:
"~*meta-webindexer" 1;
يجب السماح بـ meta-externalagent، حيث أنه المسؤول عن استخراج بيانات التعريف OG عند مشاركة الروابط على Facebook.