מבוא
החשיבות של גישה לאפליקציות מבוססות-אינטרנט במצב אופליין הולכת וגדלה. כן, כל הדפדפנים יכולים לשמור דפים ומשאבים במטמון לפרקי זמן ארוכים אם מבקשים מהם לעשות זאת, אבל הדפדפן יכול להוציא פריטים ספציפיים מהמטמון בכל שלב כדי לפנות מקום לדברים אחרים. באמצעות ממשק 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
כצפוי, אירועים נוספים נחשפים כדי לעקוב אחרי מצב המטמון. הדפדפן מפעיל אירועים לגבי דברים כמו התקדמות ההורדה, עדכון המטמון של האפליקציה ותנאי שגיאה. קטע הקוד הבא מגדיר מאזיני אירועים לכל סוג של אירוע מטמון:
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.