اضبط Vary على أسماء رؤوس الطلب التي يستخدمها خادمك لاختيار تمثيل صفحة عامة. على جهاز Mac، اختبر رأسًا واحدًا في كل مرة، وقارن المستند والبيانات الوصفية المُعادة، وتحقق من الاستجابة الافتراضية قبل تغيير الإعدادات.
هذا الدليل موجّه إلى من يتولى صيانة مستند عام ويتحقق من تقديمه عبر طرفية Mac. المثال التطبيقي هو «دليل الأشكال» اصطناعي متاح بتنسيق HTML أو نص عادي على عنوان URL واحد. تتمثل المهمة في تحديد مدخلات الاختيار الفعلية، وإعداد رأس الاستجابة المقابل، والتحقق من النتيجة.
ما الذي ينبغي أن يتضمنه رأس Vary للصفحة؟
يسمّي Vary حقول الطلب التي قد تؤثر في اختيار التمثيل، إلى جانب طريقة الطلب وعنوان URL المستهدف. وقيمه هي أسماء الرؤوس، مثل Accept، وليست أنواع الوسائط المطلوبة. فهو يصف سلوك الاختيار؛ وإضافته لا تنفّذ ذلك السلوك. RFC 9110: دلالات HTTP، القسم 12.5.5.
على سبيل المثال، إذا اختار الخادم HTML أو نصًا عاديًا باستخدام Accept، فحقل الاستجابة ذو الصلة هو Vary: Accept. وإذا اختارت طبقة التقديم أيضًا مخرجات مضغوطة أو غير مضغوطة باستخدام Accept-Encoding، فأبقِ هذا البُعد أيضًا: Vary: Accept, Accept-Encoding. هذه أمثلة مشروطة، وليست إعدادًا عامًا يصلح لكل صفحة. تفاوض المحتوى.
السؤال العملي هو: هل يمكن أن تكون استجابة مخزنة ومختارة لطلب ما غير مناسبة لطلب آخر بسبب تغيّر هذا الرأس؟ يشترط التخزين المؤقت في HTTP تطابق الحقول المحددة قبل إعادة الاستخدام دون إعادة التحقق. والحقل المحدد الغائب يطابق حقلًا غائبًا آخر، لا حقلًا حاضرًا. RFC 9111: التخزين المؤقت في HTTP، القسم 4.1.
ابدأ بكتابة قائمة بقواعد الاختيار. تحقّق من قواعد التطبيق لاختيار المستند، ومن أي تحويلات للاستجابة تُطبّق بعد ذلك. يُعد تغيّر النتيجة دليلًا مفيدًا، لكن عدم تغيّرها بين طلبين لا يثبت أن رأسًا ما غير ذي صلة بجميع القيم المدعومة.
أعدّ مصفوفة للطلبات قبل تعديل أي شيء
لنفترض أن السلوك المقصود لدليل الأشكال الاصطناعي هو تقديم HTML عند تفضيل HTML، ونص عادي عند تفضيل النص العادي، وتقديم HTML عند غياب Accept. تحتوي النسختان على المعلومات المحايدة نفسها: «دائرة، مربع، مثلث». هذه متطلبات توضيحية وليست ملاحظات من موقع منشور.
| الاختبار | إعداد الطلب | النتيجة المقصودة | ما ينبغي فحصه |
|---|---|---|---|
| HTML | Accept: text/html |
مستند HTML | المتن، وContent-Type، وVary |
| نص عادي | Accept: text/plain |
مستند نص عادي | المتن، وContent-Type، وVary |
| افتراضي | دون حقل Accept |
مستند HTML | الاختيار الافتراضي وVary |
| تكرار | HTML بعد النص العادي | مستند HTML مجددًا | ما إذا كان المتغير السابق يؤثر في التقديم |
| مدخل غير مستخدم | غيّر رأسًا غير وارد في قواعد الاختيار | التمثيل المختار نفسه | ما إذا كان هذا الرأس يحتاج إلى تحقيق |
ثبّت إعداد الضغط أثناء المقارنة الأولى. وإلا فقد يعكس اختلاف البايتات الضغط بدلًا من اختلاف المستند. تحقّق أولًا من اختيار التنسيق، ثم من الضغط على نحو منفصل. ويتماشى هذا التمييز مع الدورين المنفصلين لـAccept وAccept-Encoding. تفاوض المحتوى.
سجّل الفروق ذات الدلالة بدلًا من الاعتماد على حجم الملف وحده. في هذا المثال، ينبغي أن تتضمن استجابة النص العادي أسماء الأشكال من دون وسوم HTML، وأن يصف نوع الوسائط فيها النص العادي. وأي طابع زمني مُنشأ يتغير يستدعي التحقيق قبل اعتبار كل اختلاف في البايتات متغيرًا جديدًا.
هذه المصفوفة أداة مساعدة للتشخيص، وليست مجموعة اختبارات كاملة للتفاوض. بعد نجاح الحالات الأساسية، أضف التفضيلات المختلطة الفعلية وقيم الجودة التي تدعمها صفحتك. فالطلب البسيط الذي يحدد نوعًا واحدًا لا يختبر جميع فروع خوارزمية الاختيار.
التقط استجابات قابلة للمقارنة في طرفية Mac
ستحتاج إلى مستند اختبار عام يحتوي على مواد اصطناعية، وعنوان URL النهائي عبر HTTPS، وجهاز Mac يتوفر عليه bash وcurl. يفترض المثال أن مستند الاختبار يدعم مسبقًا سلوك HTML والنص العادي الموضّح أعلاه. وهو لا ينشئ ذلك المستند أو يحمّله أو ينشره.
افتح Terminal والصق الكتلة كاملةً أدناه. أدخل عنوان URL لمستندك الاصطناعي عند ظهور المطالبة. ينشئ البرنامج النصي مجلد تقارير مؤقتًا جديدًا، ويحفظ متن كل استجابة بجوار رؤوسها؛ ولا يستبدل تقريرًا سابقًا.
bash <<'BASH'
set -eu
printf 'Public synthetic page URL: ' > /dev/tty
IFS= read -r page_url < /dev/tty
case "$page_url" in
https://*) ;;
*) printf 'Enter an HTTPS URL.\n' >&2; exit 1 ;;
esac
report_dir=$(mktemp -d "${TMPDIR:-/tmp}/vary-check.XXXXXX")
printf 'Report directory: %s\n' "$report_dir"
for sample in html plain absent html-again; do
case "$sample" in
html|html-again) accept_header='Accept: text/html' ;;
plain) accept_header='Accept: text/plain' ;;
absent) accept_header='Accept:' ;;
esac
curl --disable --silent --show-error --fail \
--connect-timeout 5 --max-time 20 \
--header "$accept_header" \
--header 'Accept-Encoding: identity' \
--dump-header "$report_dir/$sample.headers" \
--output "$report_dir/$sample.body" \
--url "$page_url"
done
printf 'Finished. Responses saved in: %s\n' "$report_dir"
BASH
هنا، يوفّر --header حقل الطلب المضبوط، بينما يزيل Accept: حقل Accept الذي ينشئه curl داخليًا. ويحفظ --dump-header و--output الرؤوس والمتون كلًا على حدة. وتضع حدود الوقت للاتصال والنقل حدًا أقصى لكل طلب. هذه الخيارات موثقة في دليل curl.
يتوقف البرنامج النصي عندما يبلغ curl عن فشل في النقل أو عن خطأ HTTP يشمله الخيار --fail. افحص المجلد المُبلّغ عنه قبل إعادة المحاولة: فقد تبقى اللقطات السابقة، وقد تترك عملية النقل الفاشلة ملفات غير مكتملة. وهو لا يتبع عمليات إعادة التوجيه عمدًا، لذا تحقّق من سطر الحالة في كل ملف رؤوس. إذا التقطت استجابة لإعادة توجيه، فاستخدم عنوان URL النهائي للمستند وابدأ تقريرًا جديدًا. دليل curl.
افتح مجلد التقرير في Finder باستخدام المسار الذي يطبعه البرنامج النصي. وافحص الملفات في محرر نصوص عادي. قارن html.body مع plain.body، ثم قارن html.body مع html-again.body. وافحص absent.headers بعناية تضاهي استجابات التفضيلات الصريحة.
تعامل مع النتائج المحفوظة بوصفها ملاحظات مستمدة من تسلسل الطلبات هذا. فهي لا تثبت أن ذاكرة تخزين مؤقت مشتركة خزّنت أي شيء. إذا احتجت إلى اختبار إعادة استخدام الذاكرة المؤقتة، فأعد التسلسل عبر مسار التقديم المقصود ضمن شروط التخزين المؤقت الموثقة له، واعكس الترتيب أيضًا بحيث يأتي النص العادي أولًا.
طبّق النتيجة في الطبقة التي تُنشئ الاستجابة
في دليل الأشكال التوضيحي، ينبغي أن تدعم أدلة اختيار التنسيق كون Accept حقلًا للاختيار. أعد ضبطه في الموضع الذي تُنشأ فيه استجابة HTTP أو تُستكمل. إذا كانت طبقة أخرى تضيف مسبقًا عنصرًا ضروريًا إلى Vary، فأبقِه عند إضافة عنصر اختيار التنسيق. وينبغي أن تصف القائمة النهائية سلوك الاختيار المجمّع. RFC 9110: دلالات HTTP.
في ما يلي جزء من رأس الاستجابة للمثال عند تفعيل اختيار التنسيق والتفاوض على الضغط. وهو ليس استجابة HTTP كاملة ولا ملف إعدادات خادم.
Vary: Accept, Accept-Encoding
استخدم قائمة Vary المقصودة نفسها في المتغيرات المتفاوض عليها والاستجابة الافتراضية، وأبقِها في استجابات 304 Not Modified المنطبقة. توثّق MDN هذا الشرط صراحةً. أدرج مسارات الاستجابة هذه ضمن عملية التحقق بدلًا من فحص أول استجابة HTML ناجحة فقط. رأس Vary.
إن إضافة عنصر meta مع http-equiv="Vary" ليست بديلًا مدعومًا. يعرّف معيار WHATWG مجموعة محددة من توجيهات HTML التلميحية، ولا تشمل Vary، ويوضح أن هذه التوجيهات منفصلة إلى حد كبير عن رؤوس HTTP. استخدم الإعداد الفعلي لرأس الاستجابة. معيار HTML: التوجيهات التلميحية.
إذا لم تسمح واجهة النشر لديك بضبط رؤوس الاستجابة، فتحقّق مما إذا كانت طبقة الاستضافة أو التطبيق توفر دعمًا موثقًا. وعندما لا يتوفر ذلك، يتمثل أحد البدائل العملية لهذا المثال الاصطناعي في تخصيص عنواني URL منفصلين لمستندي HTML والنص العادي، بحيث تكون تمثيلاتهما ثابتة، بدلًا من التفاوض على تنسيقيهما في عنوان URL واحد. يزيل ذلك بُعد الاختيار المحدد هذا؛ أما التحويلات الأخرى فتظل بحاجة إلى تقييم مستقل.
شخّص الاختلاف الناقص أو المفرط أو المضلل
استخدم اللقطات لاختيار الخطوة التالية في التحقيق. تنطبق أداة القرار التالية على السلوك المحدد للمثال؛ وهي لا تدّعي شيئًا عن خدمة استضافة بعينها.
| الملاحظة | التحقيق التالي |
|---|---|
تنتج طلبات HTML والنص العادي تنسيقين مختلفين، لكن Vary لا يتضمن Accept |
افحص موضع تجميع رأس الاستجابة النهائي |
تتضمن المتغيرات الصريحة Accept، لكن الاستجابة الافتراضية لا تتضمنه |
افحص مسار الاستجابة الاحتياطية |
| تتلقى إعادة طلب HTML نسخة النص العادي | قارن الاختيار في المصدر بالتقديم عبر الذاكرة المؤقتة |
| تنتج كل الطلبات مستند HTML نفسه | تحقّق مما إذا كان تفاوض التنسيق موجودًا قبل إضافة عنصر متعلق بالتنسيق |
يظهر رأس غير ذي صلة في Vary |
اعثر على قاعدة الاختيار التي تستلزمه قبل إزالته |
| يؤدي تغيير حجم نافذة المتصفح إلى تغيير التخطيط من دون تغيير HTML المُقدّم | تحقّق مما إذا كان ذلك عرضًا متجاوبًا بدلًا من اختيار الخادم |
تستحق حالة غياب الرأس عن الاستجابة الافتراضية اهتمامًا خاصًا: يصف RFC 9111 كيف يمكن أن يؤدي حذف Vary من استجابة افتراضية إلى اختيارها لطلبات لاحقة رغم توفر بدائل. صحّح مسار الاستجابة الافتراضية إلى جانب المتغيرات الصريحة. RFC 9111: التخزين المؤقت في HTTP.
تجنّب استخدام Vary: * اختصارًا لقائمة لم تكتمل. بموجب قواعد التخزين المؤقت في HTTP، تفشل دائمًا الاستجابة المخزنة التي تحتوي على هذا العنصر في اختبار المطابقة. وهو لا يحدد حقول الطلب التي تختار مستندك. RFC 9111: التخزين المؤقت في HTTP.
يظل التحقق عبر المتصفح مفيدًا بعد المقارنة في الطرفية. يأخذ معيار Fetch من WHATWG رأس Vary صراحةً في الحسبان عند اختيار استجابة من ذاكرة HTTP المؤقتة. افحص المستند عبر مسار تحميله المعتاد في المتصفح، وكذلك عبر طلبات curl المضبوطة. معيار Fetch: جلب الشبكة أو ذاكرة HTTP المؤقتة.
وازن بين تقديم الصفحة ومتطلبات بحث Google
بالنسبة إلى الصفحات التي يختلف سلوكها باختلاف الجهاز، ميّز بين التصميم المتجاوب والتقديم الديناميكي. توثّق Google أن التصميم المتجاوب يقدّم HTML نفسه على عنوان URL نفسه عبر الأجهزة، بينما يختار التقديم الديناميكي HTML مختلفًا باستخدام User-Agent ويعتمد على Vary: User-Agent. وتوصي Google بالتصميم المتجاوب لسهولة تنفيذه وصيانته. أفضل ممارسات مواقع الجوال والفهرسة التي تعطي أولوية للجوال.
وبناءً على ذلك، لا يبرر دليل الأشكال الاصطناعي الذي يعيد ترتيب HTML نفسه باستخدام CSS إضافة User-Agent إلى Vary لمجرد تغيير التخطيط هذا. أما إذا كان الخادم يختار HTML مختلفًا فعليًا حسب الجهاز، فأضف حالات الأجهزة إلى مصفوفة الطلبات. كما تنصح Google بالإبقاء على المحتوى الأساسي متكافئًا بين نسختي سطح المكتب والجوال. أفضل ممارسات مواقع الجوال والفهرسة التي تعطي أولوية للجوال.
اختم بسجل موجز للتقديم يسهل مراجعته: قواعد اختيار المستند، ومصفوفة الطلبات، والاستجابات الملتقطة، وقائمة Vary الناتجة. ينبغي أن يكون لكل رأس مدرج دور محدد، وأن يظل كل متغير مدعوم قابلًا للتمييز، وأن تتبع الاستجابة الافتراضية عقد التقديم نفسه.
المصادر
- RFC 9110: دلالات HTTP — IETF / محرر RFC.
- RFC 9111: التخزين المؤقت في HTTP — IETF / محرر RFC.
- معيار Fetch — WHATWG.
- معيار HTML — WHATWG.
- curl — كيفية الاستخدام — مشروع curl.
- رأس Vary — مستندات MDN على الويب.
- تفاوض المحتوى — مستندات MDN على الويب.
- أفضل ممارسات مواقع الجوال والفهرسة التي تعطي أولوية للجوال — Google Search Central.