فهم استجابة 304 Not Modified في تخزين بيانات HTTP

عند تطوير تطبيقات الويب، يُعد التعامل مع الموارد بكفاءة أمراً بالغ الأهمية للأداء، خاصةً عندما يتعلق الأمر بالوصول إلى الملفات وتخزينها مؤقتاً في المتصفح. إحدى الطرق لتحسين هذه العملية هي من خلال الاستخدام الصحيح لاستجابة HTTP 304 Not Modified. تُعلم هذه الاستجابة المتصفح بأن المورد الذي طلبه لم يتغير منذ آخر مرة تم استرجاعه، مما يسمح للمتصفح بالاستمرار في استخدام النسخة المخزنة مؤقتاً بدلاً من تحميلها مرة أخرى. لكن كيف تعرف متى يجب إرسال هذه الاستجابة؟ دعنا نحلل ذلك خطوة بخطوة.

الرؤوس الأساسية لـ HTTP التي يجب التحقق منها

لتحديد ما إذا كان يجب إرسال استجابة 304 Not Modified، تحتاج إلى التحقق من رؤوس HTTP معينة أرسلها متصفح العميل. الرأسان الرئيسيان للتركيز عليهما هما:

  1. Etag: هذا الرأس يعمل كمعرف فريد لمورد عند إصدار معينة. يقارن المتصفح Etag المخزن مؤقتاً مع Etag الخاص بالخادم لمعرفة ما إذا كانا متطابقين.
  2. If-None-Match: هذا الرأس يرسله المتصفح ويتضمن قيمة Etag المخزنة مؤقتاً. إذا لم يتغير المورد، يمكن للخادم الرد بـ 304.

ما الذي يجب البحث عنه

  • إذا كان Etag من المتصفح موجودًا: إذا أدرج المتصفح إما رؤوس Etag أو If-None-Match في الطلب، فهذا يشير إلى أنه يمتلك نسخة مخزنة مؤقتاً من المورد.
  • اعتبارات الاقتباس: أحيانًا يقتبس المتصفحات قيمة Etag. تأكد من إزالة هذه الاقتباسات قبل المقارنة.

الرؤوس اللازمة للاستجابة الأولية

عند إرسال المورد في البداية (عادةً مع استجابة 200 OK)، من المهم تضمين الرؤوس ذات الصلة التي تُعلم المتصفح حول حالة المورد:

  • Last-Modified: يوضح آخر مرة تم فيها تغيير المورد. يمكن أن يكون هذا بمثابة تحقق بديل للتحقق من التخزين المؤقت بجانب Etag.
  • Etag (كما ذُكر سابقًا): يجب توليده للمورد وإدراجه في رؤوس الاستجابة لتسهيل عمليات التحقق من التخزين المؤقت في المستقبل.

تنفيذ المنطق

إليك مثال مبسط على pseudo-code يوضح كيفية تنفيذ المنطق لإرسال استجابة 304 Not Modified:

server_etag = gen_etag_for_this_file(myfile)
etag_from_browser = get_header("Etag")

if etag_from_browser does not exist:
    etag_from_browser = get_header("If-None-Match")
if the browser has quoted the etag:
    strip the quotes (e.g. "foo" --> foo)

set server_etag into http header

if etag_from_browser matches server_etag
    send 304 return code to browser

مثال على منطق الخادم

إليك كيف يمكنك تنفيذ ذلك في منطق الخادم لديك:

/* يجب على العميل تعيين إما Etag أو If-None-Match */
mketag(etag, &sb);

etagin = apr_table_get(r->headers_in, "Etag");
if (etagin == NULL)
    etagin = apr_table_get(r->headers_in, "If-None-Match");
if (etag != NULL && etag[0] == '"') {
    /* إزالة الاقتباسات إذا كانت موجودة */
    int sl; 
    sl = strlen(etag);
    memmove(etag, etag+1, sl+1);
    etag[sl-2] = 0;
}   

apr_table_add(r->headers_out, "ETag", etag);

if (etagin != NULL && strcmp(etagin, etag) == 0) {
    /* إذا كانت etag متطابقة، ارجع حالة 304 */
    rc = HTTP_NOT_MODIFIED;
}

الأفكار النهائية

من خلال معرفة كيفية ومتى يتم إرسال استجابة 304 Not Modified، يمكنك تقليل الحمل على الخادم بشكل فعال وتحسين تجربة المستخدم. لا تنسَ أهمية تضمين رؤوس Etag و Last-Modified أثناء الاستجابة الأولية للسماح للعميل بإجراء طلبات تحقق دقيقة من التخزين المؤقت لاحقًا. إذا كان لديك أي أسئلة حول توليد Etag أو تحتاج إلى مزيد من المساعدة في التنفيذ، فلا تتردد في التواصل للحصول على أمثلة أكثر تفصيلاً. نتمنى لك برمجة سعيدة!