מבוא
החשיבות של גישה לאפליקציות מבוססות-אינטרנט במצב אופליין הולכת וגדלה. כן, כל הדפדפנים יכולים לשמור דפים ומשאבים במטמון למשך תקופות ארוכות אם מבקשים לעשות זאת, אבל הדפדפן יכול להסיר פריטים ספציפיים מהמטמון בכל שלב כדי לפנות מקום לדברים אחרים. באמצעות ממשק ApplicationCache, HTML5 פותר חלק מהבעיות שמתעוררות במצב אופליין. השימוש בממשק המטמון מעניק לאפליקציה שלושה יתרונות:
- גלישה אופליין – המשתמשים יכולים לנווט באתר המלא שלכם כשהם במצב אופליין
- מהירות – המשאבים מגיעים ישירות מהדיסק, בלי צורך לעבור דרך הרשת.
- עמידות – אם האתר יהיה מושבת לצורך "תחזוקה" (כלומר, מישהו ישבור בטעות את הכל), המשתמשים יקבלו את חוויית השימוש אופליין
מטמון האפליקציות (או AppCache) מאפשר למפתח לציין אילו קבצים הדפדפן צריך לשמור במטמון ולהפוך לזמינים למשתמשים במצב אופליין. האפליקציה תיטען ותפעל כראוי, גם אם המשתמש לוחץ על לחצן הרענון במצב אופליין.
קובץ המניפסט של המטמון
קובץ המניפסט של המטמון הוא קובץ טקסט פשוט שמפרט את המשאבים שהדפדפן צריך לשמור במטמון לצורך גישה אופליין.
הפניה לקובץ מניפסט
כדי להפעיל את מטמון האפליקציה, צריך לכלול את מאפיין המניפסט בתג html
של המסמך:
<html manifest="example.appcache">
...
</html>
צריך לכלול את המאפיין manifest
בכל דף באפליקציית האינטרנט שרוצים לשמור במטמון. הדפדפן לא שומר דף במטמון אם הוא לא מכיל את המאפיין manifest
(אלא אם הוא מופיע באופן מפורש בקובץ המניפסט עצמו). המשמעות היא שכל דף שהמשתמש מנווט אליו שכולל manifest
יתווסף באופן משתמע למטמון האפליקציה.
לכן אין צורך לרשום את כל הדפים במניפסט. אם דף מפנה למניפסט, אין דרך למנוע שמירת הדף הזה במטמון.
כדי לראות את כתובות ה-URL שנשלטות על ידי מטמון האפליקציה, אפשר להיכנס לכתובת about://:/appcache-internals/ ב-Chrome. מכאן אפשר לנקות את המטמון ולראות את הרשומות. יש כלים דומים למפתחים ב-Firefox.
המאפיין manifest
יכול להפנות לכתובת URL מוחלטת או לנתיב יחסי, אבל כתובת URL מוחלטת חייבת להיות באותו מקור כמו אפליקציית האינטרנט.
לקובץ מניפסט יכולה להיות כל סיומת קובץ, אבל צריך להגיש אותו עם סוג ה-MIME הנכון (ראו בהמשך).
<html manifest="http://www.example.com/example.mf">
...
</html>
יש להגיש קובץ מניפסט עם סוג mime text/cache-manifest
.
יכול להיות שתצטרכו להוסיף סוג קובץ בהתאמה אישית לשרת האינטרנט או לתצורה של .htaccess
.
לדוגמה, כדי להציג את סוג ה-mime הזה ב-Apache, מוסיפים את השורה הבאה לקובץ התצורה:
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)
דרישה זו הוסרה מהמפרט לפני זמן מה, והיא לא נדרשת עוד בגרסאות העדכניות של Chrome, Safari ו-Firefox, אך נדרש סוג mime כדי לעבוד בדפדפנים ישנים יותר וב-IE11.
המבנה של קובץ מניפסט
המניפסט הוא קובץ נפרד שמקשרים אליו באמצעות מאפיין המניפסט ברכיב ה-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
שורות שמתחילות ב-'#' הן שורות תגובה, אבל הן יכולות לשמש גם למטרה אחרת. המטמון של אפליקציה מתעדכן רק כשקובץ המניפסט שלה משתנה. לדוגמה, אם אתם עורכים משאב של תמונה או משנים פונקציית JavaScript, השינויים האלה לא יישמרו מחדש במטמון. צריך לשנות את קובץ המניפסט עצמו כדי להודיע לדפדפן לרענן קבצים שנשמרו במטמון.
אל תשתמשו בחותמת זמן מתעדכנת או במחרוזת אקראית כדי לאלץ עדכונים בכל פעם. המניפסט נבדק פעמיים במהלך עדכון, פעם אחת בתחילתו ופעם אחת אחרי שכל הקבצים שנשמרו במטמון מעודכנים. אם המניפסט השתנה במהלך העדכון, יכול להיות שהדפדפן אחזר חלק מהקבצים מגרסה אחת וחלק מהקבצים מגרסה אחרת, ולכן הוא לא מחיל את המטמון ומנסה שוב מאוחר יותר.
למרות שהמטמון מתעדכן, הדפדפן לא ישתמש בקבצים האלה עד שהדף יעבור רענון, כי העדכונים מתרחשים אחרי שהדף נטען מהגרסה הנוכחית של המטמון.
מניפסט יכול לכלול שלושה קטעים נפרדים: CACHE
, NETWORK
ו-FALLBACK
.
CACHE:
- זהו הקטע שמוגדר כברירת מחדל לרשאות גישה. קבצים שמופיעים מתחת לכותרת הזו (או מיד אחרי
CACHE MANIFEST
) יישמרו באופן מפורש במטמון אחרי ההורדה הראשונה שלהם.NETWORK:
- קבצים שמפורטים בקטע הזה עשויים להגיע מהרשת אם הם לא נמצאים במטמון. אחרת, לא נעשה שימוש ברשת, גם אם המשתמש מחובר לאינטרנט. אפשר להוסיף לכאן כתובות URL ספציפיות לרשימת ההיתרים, או פשוט להזין '' כדי לאפשר את כל כתובות ה-URL. ברוב האתרים צריך להזין ''.
FALLBACK:
- קטע אופציונלי שבו מציינים דפי חלופיים אם אין גישה למשאב. ה-URI הראשון הוא המשאב, והשני הוא חלופה שמשמשת אם הבקשה לרשת נכשלת או אם מתקבלות שגיאות. שני מזהי ה-URI חייבים להיות מאותו מקור כמו קובץ המניפסט. אפשר לתעד כתובות URL ספציפיות, אבל גם קידומות של כתובות URL. "images/large/" יתעד כשלים מכתובות URL כמו "images/large/whatever/img.jpg".
המניפסט הבא מגדיר דף 'כלבו' (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
כצפוי, אירועים נוספים נחשפים כדי לעקוב אחרי מצב המטמון. הדפדפן מפעיל אירועים לגבי דברים כמו התקדמות ההורדה, עדכון מטמון האפליקציה ותנאי שגיאה. קטע הקוד הבא מגדיר פונקציות event listener לכל סוג של אירוע במטמון:
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);
אם קובץ המניפסט או משאב שצוין בו לא יורדים, כל העדכון נכשל. במקרה כזה, הדפדפן ימשיך להשתמש במטמון האפליקציה הישן.
קובצי עזר
- מפרט ה-API של ApplicationCache
- Application Cache is a douchebag – סקירה של הבעיות והמלכודות ב-AppCache.