مقدمه
دسترسی به برنامه های مبتنی بر وب به صورت آفلاین به طور فزاینده ای اهمیت پیدا می کند. بله، همه مرورگرها میتوانند صفحات و منابع را برای مدتهای طولانی در حافظه پنهان نگه دارند، اما مرورگر میتواند موارد جداگانه را در هر نقطه از حافظه پنهان خارج کند تا جایی برای چیزهای دیگر باز کند. HTML5 برخی از مزاحمت های آفلاین بودن را با رابط ApplicationCache برطرف می کند. استفاده از رابط کش به برنامه شما سه مزیت می دهد:
- مرور آفلاین - کاربران وقتی آفلاین هستند می توانند سایت کامل شما را پیمایش کنند
- سرعت - منابع مستقیماً از دیسک می آیند، بدون سفر به شبکه.
- انعطاف پذیری - اگر سایت شما برای "نگهداری" از کار بیفتد (مثلاً، شخصی به طور تصادفی همه چیز را خراب کند)، کاربران شما تجربه آفلاین را دریافت خواهند کرد.
Application Cache (یا AppCache) به توسعهدهنده اجازه میدهد تا مشخص کند که مرورگر چه فایلهایی را باید در حافظه پنهان نگه دارد و در دسترس کاربران آفلاین قرار دهد. برنامه شما بارگیری میشود و به درستی کار میکند، حتی اگر کاربر دکمه تازهسازی را در حالی که آفلاین است فشار دهد.
فایل مانیفست کش
فایل مانیفست کش یک فایل متنی ساده است که منابعی را که مرورگر باید برای دسترسی آفلاین ذخیره کند فهرست می کند.
ارجاع به یک فایل مانیفست
برای فعال کردن حافظه پنهان برنامه برای یک برنامه، ویژگی manifest را در تگ html
سند قرار دهید:
<html manifest="example.appcache">
...
</html>
ویژگی manifest
باید در هر صفحه از برنامه وب شما که میخواهید در حافظه پنهان ذخیره شود، گنجانده شود. اگر صفحهای حاوی ویژگی manifest
نباشد، مرورگر آن را کش نمیکند (مگر اینکه صریحاً در خود فایل مانیفست فهرست شده باشد. این بدان معناست که هر صفحهای که کاربر به آن هدایت میکند که شامل یک manifest
باشد، به طور ضمنی به حافظه پنهان برنامه اضافه میشود. ، نیازی به فهرست کردن هر صفحه در مانیفست شما نیست.
با مراجعه به http://appcache-internals/ در کروم میتوانید آدرسهای اینترنتی را که توسط حافظه پنهان برنامه کنترل میشوند، مشاهده کنید. از اینجا می توانید کش ها را پاک کرده و ورودی ها را مشاهده کنید. ابزارهای توسعه دهنده مشابهی در فایرفاکس وجود دارد.
مشخصه manifest
می تواند به یک URL مطلق یا مسیر نسبی اشاره کند، اما یک URL مطلق باید در همان مبدا برنامه وب باشد. یک فایل مانیفست میتواند هر پسوند فایلی داشته باشد، اما باید با نوع mime درست ارائه شود (به زیر مراجعه کنید).
<html manifest="http://www.example.com/example.mf">
...
</html>
یک فایل مانیفست باید با text/cache-manifest
ارائه شود. ممکن است لازم باشد یک نوع فایل سفارشی را به وب سرور یا پیکربندی .htaccess
. اضافه کنید.
به عنوان مثال، برای ارائه این نوع mime در آپاچی، این خط را به فایل پیکربندی خود اضافه کنید:
AddType text/cache-manifest .appcache
یا در فایل app.yaml خود در Google App Engine:
- url: /mystaticdir/(.*\.appcache)
static_files: mystaticdir/\1
mime_type: text/cache-manifest
upload: mystaticdir/(.*\.appcache)
این الزام مدتی پیش از مشخصات حذف شد و دیگر مورد نیاز آخرین نسخه های کروم، سافاری و فایرفاکس نیست، اما برای کار در مرورگرهای قدیمی و IE11 به نوع mime نیاز دارید.
ساختار یک فایل مانیفست
مانیفست فایل جداگانه ای است که از طریق ویژگی manifest در عنصر html به آن پیوند می دهید. یک مانیفست ساده چیزی شبیه به این است:
CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js
http://cdn.example.com/scripts/main.js
این مثال چهار فایل را در صفحه ای که این فایل مانیفست را مشخص می کند، کش می کند.
چند نکته قابل توجه است:
- رشته
CACHE MANIFEST
اولین خط است و لازم است. - فایل ها می توانند از دامنه دیگری باشند
- برخی از مرورگرها محدودیتهایی را برای میزان فضای ذخیرهسازی موجود برای برنامه شما اعمال میکنند. به عنوان مثال، در Chrome، AppCache از یک مخزن مشترک ذخیره سازی موقت استفاده می کند که سایر API های آفلاین می توانند به اشتراک بگذارند. اگر در حال نوشتن برنامهای برای فروشگاه وب Chrome هستید، استفاده از
unlimitedStorage
این محدودیت را حذف میکند. - اگر مانیفست خود 404 یا 410 را برگرداند، کش حذف می شود.
- اگر مانیفست یا منبع مشخص شده در آن دانلود نشود، کل فرآیند بهروزرسانی حافظه پنهان با شکست مواجه میشود. در صورت خرابی، مرورگر به استفاده از حافظه پنهان برنامه قدیمی ادامه خواهد داد.
بیایید به یک مثال پیچیده تر نگاه کنیم:
CACHE MANIFEST
# 2010-06-18:v2
# Explicitly cached 'master entries'.
CACHE:
/favicon.ico
index.html
stylesheet.css
images/logo.png
scripts/main.js
# Resources that require the user to be online.
NETWORK:
*
# static.html will be served if main.py is inaccessible
# offline.jpg will be served in place of all images in images/large/
# offline.html will be served in place of all other .html files
FALLBACK:
/main.py /static.html
images/large/ images/offline.jpg
خطوطی که با "#" شروع می شوند، خطوط نظر هستند، اما می توانند هدف دیگری نیز داشته باشند. کش یک برنامه تنها زمانی به روز می شود که فایل مانیفست آن تغییر کند. بنابراین، برای مثال، اگر یک منبع تصویر را ویرایش کنید یا یک تابع جاوا اسکریپت را تغییر دهید، این تغییرات دوباره ذخیره نمیشوند. شما باید خود فایل مانیفست را تغییر دهید تا به مرورگر اطلاع دهید تا فایلهای ذخیرهشده را بازخوانی کند .
از استفاده از مهر زمانی یا رشته تصادفی که به طور مداوم به روز می شود برای اجبار به روز رسانی هر بار استفاده نکنید. مانیفست دو بار در حین به روز رسانی، یک بار در شروع و یک بار پس از به روز رسانی تمام فایل های کش شده بررسی می شود. اگر مانیفست در طول بهروزرسانی تغییر کرده باشد، ممکن است مرورگر برخی از فایلها را از یک نسخه و فایلهای دیگر را از نسخه دیگر دریافت کرده باشد، بنابراین حافظه پنهان را اعمال نمیکند و بعداً دوباره امتحان میکند.
اگرچه حافظه پنهان بهروزرسانی میشود، اما مرورگر تا زمانی که صفحه بهروزرسانی نشود از آن فایلها استفاده نمیکند، زیرا بهروزرسانیها پس از بارگیری صفحه از نسخه فعلی کش انجام میشود.
مانیفست میتواند سه بخش مجزا داشته باشد: CACHE
، NETWORK
و FALLBACK
.
-
CACHE:
- این بخش پیش فرض برای ورودی ها است. فایلهای فهرستشده در زیر این سرصفحه (یا بلافاصله بعد از
CACHE MANIFEST
) پس از بارگیری برای اولین بار بهصراحت در حافظه پنهان ذخیره میشوند.NETWORK:
- فایلهای فهرستشده در این بخش، اگر در حافظه پنهان نباشند، ممکن است از شبکه بیایند، در غیر این صورت، حتی اگر کاربر آنلاین باشد، از شبکه استفاده نمیشود. شما می توانید URL های خاص را در اینجا لیست سفید کنید، یا به سادگی " "، که به همه URL ها اجازه می دهد. اکثر سایت ها به " " نیاز دارند .
FALLBACK:
- یک بخش اختیاری که صفحات بازگشتی را در صورت غیرقابل دسترسی بودن منبع مشخص می کند. URI اول منبع است، دومی بازگشتی است که در صورت شکست درخواست شبکه یا خطا استفاده می شود. هر دو URI باید از همان مبدأ فایل مانیفست باشند. شما می توانید URL های خاص و همچنین پیشوندهای URL را ضبط کنید. "images/large/" از آدرس های اینترنتی مانند "images/large/whatever/img.jpg" شکست می خورد.
مانیفست زیر یک صفحه "catch-all" (offline.html) را تعریف می کند که وقتی کاربر سعی می کند در حالت آفلاین به ریشه سایت دسترسی پیدا کند، نمایش داده می شود. همچنین اعلام می کند که همه منابع دیگر (به عنوان مثال منابع موجود در یک سایت از راه دور) به اتصال به اینترنت نیاز دارند.
CACHE MANIFEST
# 2010-06-18:v3
# Explicitly cached entries
index.html
css/style.css
# offline.html will be displayed if the user is offline
FALLBACK:
/ /offline.html
# All other resources (e.g. sites) require the user to be online.
NETWORK:
*
# Additional resources to cache
CACHE:
images/logo1.png
images/logo2.png
images/logo3.png
در حال به روز رسانی کش
هنگامی که یک برنامه آفلاین است، تا زمانی که یکی از موارد زیر رخ دهد، در حافظه پنهان باقی می ماند:
- کاربر فضای ذخیره سازی داده های مرورگر خود را برای سایت شما پاک می کند.
- فایل مانیفست اصلاح شده است. توجه: بهروزرسانی یک فایل فهرست شده در مانیفست به این معنی نیست که مرورگر آن منبع را دوباره کش میکند. خود فایل مانیفست باید تغییر کند.
وضعیت حافظه پنهان
شی window.applicationCache
دسترسی برنامهای شما به حافظه پنهان برنامه مرورگر است. ویژگی status
آن برای بررسی وضعیت فعلی کش مفید است:
var appCache = window.applicationCache;
switch (appCache.status) {
case appCache.UNCACHED: // UNCACHED == 0
return 'UNCACHED';
break;
case appCache.IDLE: // IDLE == 1
return 'IDLE';
break;
case appCache.CHECKING: // CHECKING == 2
return 'CHECKING';
break;
case appCache.DOWNLOADING: // DOWNLOADING == 3
return 'DOWNLOADING';
break;
case appCache.UPDATEREADY: // UPDATEREADY == 4
return 'UPDATEREADY';
break;
case appCache.OBSOLETE: // OBSOLETE == 5
return 'OBSOLETE';
break;
default:
return 'UKNOWN CACHE STATUS';
break;
};
برای بررسی برنامهنویسی بهروزرسانیهای مانیفست، ابتدا applicationCache.update()
را فراخوانی کنید. با این کار سعی می شود حافظه پنهان کاربر (که نیاز به تغییر فایل مانیفست دارد) را به روز کند. در نهایت، زمانی که applicationCache.status
در وضعیت UPDATEREADY
خود قرار دارد، با فراخوانی applicationCache.swapCache()
کش قدیمی را با کش جدید تعویض می کند.
var appCache = window.applicationCache;
appCache.update(); // Attempt to update the user's cache.
...
if (appCache.status == window.applicationCache.UPDATEREADY) {
appCache.swapCache(); // The fetch was successful, swap in the new cache.
}
خبر خوب: شما می توانید این را خودکار کنید. برای به روز رسانی کاربران به جدیدترین نسخه سایت خود، شنونده ای را تنظیم کنید تا رویداد updateready
را در بارگذاری صفحه نظارت کند:
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
رویدادهای AppCache
همانطور که ممکن است انتظار داشته باشید، رویدادهای اضافی برای نظارت بر وضعیت کش در معرض دید قرار می گیرند. مرورگر رویدادها را برای مواردی مانند پیشرفت دانلود، بهروزرسانی حافظه پنهان برنامه و شرایط خطا فعال میکند. قطعه زیر شنوندگان رویداد را برای هر نوع رویداد حافظه پنهان تنظیم می کند:
function handleCacheEvent(e) {
//...
}
function handleCacheError(e) {
alert('Error: Cache failed to update!');
};
// Fired after the first cache of the manifest.
appCache.addEventListener('cached', handleCacheEvent, false);
// Checking for an update. Always the first event fired in the sequence.
appCache.addEventListener('checking', handleCacheEvent, false);
// An update was found. The browser is fetching resources.
appCache.addEventListener('downloading', handleCacheEvent, false);
// The manifest returns 404 or 410, the download failed,
// or the manifest changed while the download was in progress.
appCache.addEventListener('error', handleCacheError, false);
// Fired after the first download of the manifest.
appCache.addEventListener('noupdate', handleCacheEvent, false);
// Fired if the manifest file returns a 404 or 410.
// This results in the application cache being deleted.
appCache.addEventListener('obsolete', handleCacheEvent, false);
// Fired for each resource listed in the manifest as it is being fetched.
appCache.addEventListener('progress', handleCacheEvent, false);
// Fired when the manifest resources have been newly redownloaded.
appCache.addEventListener('updateready', handleCacheEvent, false);
اگر فایل مانیفست یا منبع مشخص شده در آن دانلود نشود، کل به روز رسانی با شکست مواجه می شود. در صورت بروز چنین مشکلی، مرورگر به استفاده از حافظه پنهان برنامه قدیمی ادامه خواهد داد.
مراجع
- مشخصات ApplicationCache API
- Application Cache یک کیسه دوشی است - مشکلات و مشکلات AppCache را پوشش می دهد.