الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

درس: If-Modified-Since

بدأه eech55 في 2 أغسطس 2006 · 3 رد · 1,152 مشاهدة · في منتدى تصميم صفحات الويب
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم اخوتي..

في هذا الموضوع سأكتب درسا عن كيفية إستخدام الـ If-Modified-Since مع الصفحات الديناميكية.. فللأسف كثير من الصفحات الديناميكية تتجاهل هذه الخاصية المفيدة حتى الكثير من البرامج الأجنبية.. مثلا phpbb لا يقوم بتطبيق هذا إلا من خلال mod.. ولهذا السبب أرى أنه من الضروري كتابة موضوع عن هذا العنصر المهجور من قبل معظم مبرمجي الصفحات الديناميكية.

الفهرس

1- مقدمة لفتح الشهية

2- كيفية عمل المواقع بصفة عامة

3- المشكلة بصفة عامة

4- كيفية تعامل الصفحات الثابته الغير ديناميكية مع if-modified-since

5- كيفية تعامل الصفحات الديناميكية مع if-modified-since

6- الحل مع الصفحات الديناميكية

7- معلومات إضافية

1- مقدمة لفتح الشهية

هل لديك موقع على الشبكة ولديك عرض نطاق ترددي محدود شهريا؟ monthly bandwidth limit

هل تريد زيادة سرعة دخول الزائر لصفحات موقعك بشكل ملحوظ من دون زيادة الـ bandwidth؟

و في نفس الوقت تقلل من استهلاك الـ monthly bandwidth limit؟

بعد قرائتك هذا الدرس ستتمكن من معرفة الكيفيات والحيثيات مع الأمثلة والنهاية هي رضى الزائر من خلال زيادة سرعة دخول الموقع + ورضاك من خلال الحفاظ على الـ bandwidth وليس فقط هذا بل الـ CPU/RAM في خادم الإستضافه

انا مشغول حاليا وسأعود لاحقا لإكمال الدرس..

اخوكم

إذا نفعتك أحد مشاركاتي فأدع بظهر الغيب لوالداي بالصحة والسلامة والسعادة وطول العمر وأن يكون هذا زيادة لهما في كل خير.

post-21836-1257612765.gif

before asking: smart questions how-to

#2

أنا على أحر من الجمر سنتابع ومشكور مقدماً

ولو وافيت ربك دون ذنب *** وناقشك الحساب إذاً هلكتا

ولم يظلمك في عملٍ ولكن *** عسير أن تقوم بما حملتا

#3

مرحبا بك أخي أبو محمد اللحياني.. وجميع الإخوة

الحماس موجود وبسم الله نبدأ

If-Modified-Since

الفهرس

1- المقدمة ---- في الرد الأول :)

2- كيفية عمل المواقع بصفة عامة

3- المشكلة بصفة عامة

4- كيفية تعامل الصفحات الثابته الغير ديناميكية مع if-modified-since

5- كيفية تعامل الصفحات الديناميكية مع if-modified-since

6- الحل مع الصفحات الديناميكية

7- مثال عملي مع لغة Perl

8- معلومات إضافية

====================

2- كيفية عمل المواقع بصفة عامة

لنقل على سبيل المثال أنك ويب ماستر و لديك اشتراك موقع على احدى الخوادم و بطبيعة الحال سيكون لديك monthly bandwidth limit.

ونفرض أنك قمت ببرمجة هذا الموقع بإستخدام بعض اللغات كالـ Perl - php - asp - phython وغيرهم وتستمد محتويات الموقع من قاعدة بيانات mysql

نفرض أن احد الاشخاص أراد زيارة موقعك، ويقوم هذا بإدخال عنوان الموقع في address bar ثم enter وهنا تحدث هذه الخطوات بصفة عامة:

1- يرسل طلب للخادم يذكر فيه انه يريد مشاهدة الموقع

2- الخادم يستقبل الطلب ويرسل ردا إلى الزائر ويخبره بمحتويات تلك الصفحة، يعني يرسل له صفحة html و الصور والفلاشات وكل شيء

3- متصفح الإنترنت عند الزائر -- internet explorer مثلا -- سيستقبل الطلب ويقوم بعرضه بالوجه المطلوب بالإضافة أنه سيقوم بحفظ نسخة من الموقع في الهارديسك وإسمه cache في FireFox و Internet explorer تسميه temporary internet files

طبعا في الخطوة رقم 2 تم استهلاك جزء ليس بالهين من الـ monthly bandwidth ولكن هذا أمر لا مفر منه فهذه الطريقة الوحيدة لإرسال الموقع

حتى الآن كل شيء سهل و على مايرام :)

3- المشكلة بصفة عامة

المشكلة تبدأ عندما يريد المستخدم من معاودة زيارة موقعك مرة أخرى.. ونفرض أنك لم تقم بتغيير محتويات الصفحة ولم تضف أي جديد في قاعدة البيانات لديك.. فماذا تتوقع أن يحدث؟

التخمين المبدئي -- من دون دراية كافية -- سيكون أن المفروض أن يستخدم الـ client الـ cache حيث أنه لا يوجد تغيير في الموقع ولا داعي لإعادة إرسال ماتم إرساله وايضا المستخدم لديه نسخة في الـ cache..

لكن المشكلة هي أن متصفح الإنترنت سيرسل طلب جديد وخادم المواقع سيرسل صفحة الـ html من جديد ويضيع الـ monthly b/w limit من دون فائدة بالإضافة أن وقت المستخدم سيضيع حيث أن سرعة الكاش أسرع بكثير من سرعة إنزال الصفحة تلك من جديد.

4- كيفية تعامل الصفحات الثابته الغير ديناميكية مع if-modified-since

المثال السابق كان مبنيا أنك برمجت الموقع بـ php/perl/python/asp أو اي صفحة ديناميكية أخرى

والآن سأضرب المثال مبنيا على أنك تستخدم صفحة غير ديناميكية -- يعني صفحة .html

حتى تتبين القضية بشكل سليم وواضح، سأضرب مثالين للصفحات الثابته او الـstatic

مثال إرسال الزائر طلب رؤية الموقع للمرة الأولى

1- متصفح الإنترنت عند الزائر يرسل طلب

2- الخادم يستقبل الطلب

3- الخادم يرسل ردا، والجديد هنا أن الخادم سيقوم بوضع خانة إضافية داخل هذا الرد -- والتي لا يضعها مع الصفحات الديناميكية -- هذه الخانة إسمها Last-Modified وتحتوي على التاريخ والوقت الذين تم بهما آخر تعديل لتلك الصفحة (مزيد من التفاصيل لاحقا)

4- سيستقبل متصفح الإنترنت عند الزائر هذه المعلومات ويعرضها للزائر بالإضافة أنه سيقوم بتخزين الموقع في الـ cache كما أنه سيحافظ على التاريخ والوقت الذين حصل عليهما من خلال Last-Modified

مثال إرسال الزائر طلب رؤية الموقع للمرة الأخرى

هنا ستتم خطوات إضافية لأن المتصفح الآن يملك معلومات إضافية وهي الـlast-modified

لنقل ان المستخدم أرسل طلبا إلى خادم الموقع مرة أخرى فماذا سيحدث؟ التالي:-

1- متصفح الإنترنت سيرسل طلب إلى الموقع وسيضع خانة إضافية في هذا الطلب إسمها If-Modified-Since وهذه الخانة تحتوي وقت وتاريخ حصل عليهما من خلال الـ Last-Modified في المثال السابق

2- الخادم يستقبل الطلب، وسيجد تلك الخانة وهي if-modified-since ويقرأ التاريخ والوقت في الخانة

3- الخادم سيقوم بعملية مقارنة بين شيئين. سينظر فيما إذا كانت نسخة ملف الـ .html قد طرأ عليها تغيير بعد الوقت الذي حصل عليه في الطلب (if-modified-since) وإذا لم يطرأ التغيير منذ ذلك الوقت فإن الخادم لــــن يرسل نسخة كاملة لتلك الصفحة إنما سيرسل رسالة صغيرة إلى الزائر تحتوي على Not Modified

4- الزائر يستقبل not modified وسيستخدم الـcache

لو تلاحظ في هذه الحالة الخادم لم يستهلك سوا جزء يسير جدا من الـmonthly bandwidth

وكذلك لم حافظ على جزء من الـ RAM/CPU

بالإضافة أن المستخدم انبهر بسرعة الموقع الخيالية

لكن هناك سؤال يشغل بال الكثيرين وهو كيف قام الخادم بعملية المقارنة في الخطوة رقم 3؟ كيف تمكن من معرفة فيما إذا كان قد طرأ على الملف تعديل ام لا؟

كما تعلمون أن كل ملف يحتوي على بيانات إضافية، مثلا كل ملف يحتوي على permissions ويحتوي على create time - modify time - access time بالإضافة إلى العديد والعديد وهذا يعتمد على الـ File System

ففي الخطوة رقم 3 قام الخادم بقراءة الـ modify time لذلك الملف -- .html -- وبناءا على هذا الوقت والتاريخ تمت المقارنة مع التاريخ والوقت الذين حصل عليهما من طلب الزائر في if-modified-since

بالإضافة أن الخادم يستخدم التقنية ذاتها في إرسال وقت الـ Last-Modified كما تبين في المثال الأول

هذا كان مع الصفحات الثابته -- static -- لكن ماذا عن الصفحات الديناميكية؟ كما تبين سابقا أنه لن يتم استخدام الـcache مع الصفحات الديناميكية.. فيا ترى ماهو السبب وكيف تقوم بحل هذه المشكلة؟

5- كيفية تعامل الصفحات الديناميكية مع if-modified-since

كما تبين في المثال السابق مع الصفحات السابقة فإن الخادم يقرأ تاريخ modify time من الملف ويعتبرها وسيلة موثوقه لمعرفة فيما اذا كان هناك تغيير في الملف او لا.. وهذا امر منطقي ومعقول جدا ففي كل مرة يتم تغير الصفحات الثابته يتغير هذا الوقت لأنه بصفة عامة تغيير على الملف بعينه

لكن مع الصفحات الديناميكية وخاصة المرتبطة بقواعد البيانات فالتغيرالحاصل في محتوى الموقع ليس بالضرورة تغيير في محتوى الملف. على سبيل المثال هذا المنتدى يحتوي على ملف اسمه index.php ويقوم بعرض جميع الاقسام والمنتديات. وفرضا لو قلنا أنه قام الwebmaster بإضافة قسم أو منتدى فإن هذه الإضافة ستكون فقط في قاعدة البيانات وسيبقى ملف الـindex.php كما هو لم يتغير وبالتالي وقت الـ modify time كما كان لم يتغير بالرغم من تغير محتوى الموقع.

لهذا السبب فخوادم المواقع ذكية فبمجرد معرفتها أن هذه الصفحة ديناميكية فإنها لا ترسل الـLast-Modified ومتصفح الإنترنت عند الزائر إذا لم يحصل على Last-Modified فإنه لن يرسل if-modified-since لانه اصلا لا يعلم قيمة last-modified اساسا.. و حتى لو فرضنا جدلا أن الزائر كان مشاغبا و قام بإرسال if-modified-since هكذا عبثا فإن الخادم سيتجاهل الخانة ولن يقوم بإجراء المقارنة تلك والذي بدوره يؤدي إلى عدم إرسال رسالة Not Modified...

مع ذكاء خادمات المواقع هذا تم تجنب مشكلة وهي تمكن الزائر من مشاهدة معلومات حديثة مع الحيلولة دون اجبار الزائر لحذف الـcache لديه.

لكن تظل هناك مشكلة كبيرة وهي في حالة لم يتم تغيير محتويات تلك الصفحة، حيث أنه تم ضياع جزء من الـmonthly bandwidth limit بالإضافة إلى جزء من الـ RAM/CPU.. والأهم من ذلك سيفقد المستخدم الإستمتاع بالسرعة الرهيبة التي ذاقها مع الصفحات الثابته.

6- الحل مع الصفحات الديناميكية

الحل يعجب عشاق البرمجة.. و هو من خلال القيام بالتالي:

1- يجب عليك إرسال خانة Last-Modified تحتوي على وقت وتاريخ يعبران عن تاريخ آخر تحديث

2- يجب عليك إستقبال If-Modified-Since من طلبات الزوار وأخذ القرار فيما اذا كان عليك إرسال الصفحة كاملة إم فقط إرسال رسالة تحتوي على Not-Modified

لتطبيق الخطوة رقم 1 عليك بمشاهدة قاعدة البيانات لديك ومعاينة تاريخ ووقت آخر تعديل قد تم فيما يتعلق بصفحة index.php وثم تقوم بإرسال هذه القيمة مع إجابة طلب الزائر.

لتطبيق الخطوة رقم 2 عليك بقراءة خانة if-modified-since والتي قد حصلت عليها من خلال طلب الزوار. ثم تقارن تلك القيمة مع تاريخ ووقت آخر تعديل في قاعدة البيانات، فإذا كان التاريخ في قاعدة البيانات أكبر من التاريخ المعطى فيجب عليك بعدم إرسال Not Modified و إلا لن يتمكن الزائر من مشاهدة التحديثات إلا بعد مسح الكاش، و أما في حال كانت القيمة المعطاة أقل أو تساوي تلك القيمة في قاعدة البيانات فيجب إرسال رد يحتوي على Not Modified ليستمتع الزائر بالسرعة كما استمتع مع الصفحات الثابته.

7- مثال عملي مع لغة Perl

هذا المثال بحبيبة القلب -- Perl -- وهي لغة شائعة جدا ولها استخدامات عديدة وهي أكبر من مجرد لغة لبرمجة المواقع فهي مشهورة بتعديل النصوص على اليونكس ويكاد لا يخلو نظام تشغيل يونكس إلا ويحتوي على نسخة من لغة برمجة Perl .وهذه اللغة أقدم من PHP و مع العلم أن أول إصدارة PHP قد تم برمجتها من خلال Perl، لكن الإصدارات الحديثة من PHP منفصلة تماما وهي لغة قوية أيضا ولها شعبيتها. ومديحي للـ Perl لا ينقص من الـPHP شيء ولا أي لغة أخرى.

طبعا القضية هي فهمية بحته ويمكنكم استخدام اي لغة تريدونها

كما أرجو ملاحظة أن جميع ما يأتي بعد علامة الـ # فهو ملاحظة ولا يعتبر جزء من الشفرة

#!/usr/bin/perl
use warnings;
use strict;
use CGI;
use DBI;

my $cgi=new CGI;

## db connection variables
my $dbname='mydatabase';
my $dbuname='myusername';
my $dbpword='mYsUperPASSwd213i';
my $dbhostname='db1.server.name';
my $dbport='3306';

## connection to database
my $dbh=DBI->connect("dbi:mysql:database=$dbname;host=$dbhostname;port=$dbport",$dbuname,$dbpword) or die "unable to connect";

## query for date and time values to find when last editions accured
my $sth->prepare("SELECT date FROM table_1 ORDER BY date DESC limit 1");
$sth->execute();

## we found the right time and will be stored in this variable
my $last_modified=$sth->fetchrow_array();
$sth->finish;

## then we recieve HTTP requests and seek for "if-modified-since" value
my $if_modified_since=$ENV{HTTP_IF_MODIFIED_SINCE};

## now we compare the two values and decide the right action :)

if ($last_modified <= $if_modified_since) {
	print $cgi->header(-status=>304); # 304 means Not Modified :)
	exit; # it's important to stop this process to save ram/cpu/bandwidth
	$dbh->disconnect;
}


## if site is modified, then we surly need to send the modified version :)

my $sth->prepare("SELECT news FROM table_1 ORDER BY date DESC limit 5"); # to show newest 5
$sth->execute();

## printing site content -- the header

print $cgi->header(-Last_Modified=>$last_modified);
print <<HEADER;
<html>
<head><title>site title</title></head>
<body>
<p>welcome to my smart super fast dynamic page<br>
here are five newest entries I've added to my database:</p>
HEADER

## printing last added news as fetched from the database
foreach ($sth->fetchrow_array()) {
print $_,"<br>\n";
}
$sth->finish;

## closing html tags + copy writes
print <<TAIL;
All rights reseved to eech55
</body>
</html>
TAIL

$dbh->disconnect;

8- معلومات إضافية

هناك أدوات بالتأكيد ستساعدك لمعاينة الإسكربت ومعرفة فيما اذا كان كل شيء كما يرام أو لا.. أحد تلك البرامج هي Live HTTP headers وهو برنامج يتم تنصيبه على firefox ويقوم بطباعة جميع محتويات الـ http request and replay headers كما أنه مجاني :)

ويمكنكم الحصول عليه من خلال هذا الموقع https://addons.mozilla.org/firefox/575/

ملاحظة صغيرة وهي أن المثال السابق يستمد التاريخ من قاعدة البيانات فقط وهذا للتبسيط، و يجب عليك أن تستمد التاريخ أيضا من تاريخ تعديل ملف الإسكربت نفسه وثم تعتبر احدثهم الـ last modified، بالإضافة إلى القوالب -- templates -- ففي حال استخدامك للقوالب عليك أيضا البحث عن تاريخ تعديل ملفات القوالب. لكن لا يجب عليك البحث عن تواريخ تعديل ملفات الصور والفلاش لأن الخادم يعاملها معاملة الـ static pages

أيضا ملاحظة صغيرة، وقد تواجهكم.. وهي أن متصفح الإنترنت عند الزائر لا يقوم بإرسال الـ if-modified-since وهذا بكل بساطه لأنه لم يحصل على last-modified.. لذا تأكد من إرسال الـ last-modified في كل مرة تجيب على طلبات الزوار

والذي يريد نشر الدرس لمواقع أخرى فله الحق في ذلك ولا مانع لدي لكن مع مراعات وضع رابط لهذه الصفحة

اخوكم

إذا نفعتك أحد مشاركاتي فأدع بظهر الغيب لوالداي بالصحة والسلامة والسعادة وطول العمر وأن يكون هذا زيادة لهما في كل خير.

post-21836-1257612765.gif

before asking: smart questions how-to

#4

فقط للتوضيح وتجنب الإلتباس

انا قلت

اقتباس
كما تعلمون أن كل ملف يحتوي على بيانات إضافية، مثلا كل ملف يحتوي على permissions ويحتوي على create time - modify time - access time بالإضافة إلى العديد والعديد وهذا يعتمد على الـ File System

هو في الحقيقة ليس داخل الملف.. مثلا مع الـ EXT2/3 او الـ UFS يتم تخزينه في مايسمى بالـ inode

الخلاصة أنه يعتمد على الـ File System اين يخزن تلك المعلومات بالضبط

إذا نفعتك أحد مشاركاتي فأدع بظهر الغيب لوالداي بالصحة والسلامة والسعادة وطول العمر وأن يكون هذا زيادة لهما في كل خير.

post-21836-1257612765.gif

before asking: smart questions how-to

مواضيع مشابهة