ממשקי API לאחסון

כמעט כל היבט בפיתוח האפליקציה כולל אלמנט כלשהו של שליחה או קבלה של נתונים. תאריך ההתחלה: בעקרונות הבסיסיים, כדאי להשתמש ב-framework של MVC כדי לעזור לכם לתכנן ולהטמיע את האפליקציה שלכם הנתונים לא קשורים בכלל לתצוגה של האפליקציה על הנתונים האלה (ראו ארכיטקטורת MVC).

צריך גם לחשוב על אופן הטיפול בנתונים כשהאפליקציה במצב אופליין (מידע נוסף זמין במאמר קודם כל במצב אופליין). במסמך הזה מוצגות בקצרה את אפשרויות האחסון לשליחה, קבלה ושמירה של נתונים באופן מקומי; ה בשארית המסמך מוסבר איך להשתמש בממשקי ה-API של מערכת הקבצים ו-Sync File System ב-Chrome (ראו גם ב-fileSystem API וב-syncFileSystem API).

אפשרויות אחסון

אפליקציות ארוזות משתמשות במנגנונים רבים ושונים לשליחה ולקבלה של נתונים. לנתונים חיצוניים (משאבים, בדפי אינטרנט), עליכם להיות מודעים ל-Content Security Policy (CSP). דומה ל-Chrome תוספים, אפשר להשתמש ב-XMLHttpRequests ממקורות שונים כדי לתקשר עם שרתים מרוחקים. שלך יכול גם לבודד דפים חיצוניים, כדי ששאר חלקי האפליקציה יהיו מאובטחים (מידע נוסף זמין במאמר הטמעת אינטרנט חיצוני) ).

כששומרים נתונים באופן מקומי, אפשר להשתמש ב-Chrome Storage API כדי לשמור כמויות קטנות של מחרוזות ואת IndexedDB כדי לשמור נתונים מובְנים. באמצעות IndexedDB, ניתן לשמור אובייקטי JavaScript אחסון אובייקטים ולהשתמש באינדקסים של החנות כדי לבצע שאילתות על נתונים (למידע נוסף, עיינו במאמר Simple Todo של HTML5 Rock הצגת רשימה של המדריך). לכל סוגי הנתונים האחרים, כמו נתונים בינאריים, יש להשתמש ב-Filesystem וב-Sync ממשקי API של מערכת הקבצים.

ממשקי ה-API של מערכת הקבצים ו-Sync Filesystem ב-Chrome מרחיבים את HTML5 FileSystem API. עם ממשק API של מערכת הקבצים, אפליקציות יכולות ליצור, לקרוא, לנווט ולכתוב בקטע שנמצא בארגז חול (sandbox) של מערכת הקבצים המקומית. לדוגמה, אפליקציה לשיתוף תמונות יכולה להשתמש ב-Filesystem API כדי לקרוא ולכתוב כל תמונות שהמשתמש בוחר.

באמצעות Sync Filesystem API של Chrome, אפליקציות יכולות לשמור ולסנכרן נתונים ב-Google Drive של המשתמש, כדי שאותם נתונים יכולים להיות זמינים בקרב לקוחות שונים. לדוגמה, טקסט שמגובה בענן שאפליקציית העורך יכולה לסנכרן באופן אוטומטי קובצי טקסט חדשים עם חשבון Google Drive של המשתמש. כאשר משתמש פותח את עורך הטקסט בלקוח חדש, Google Drive דוחף קובצי טקסט חדשים למופע הזה של בכלי לעריכת טקסט.

שימוש ב-Chrome Filesystem API

הוספת הרשאה למערכת הקבצים

כדי להשתמש ב-File System API של Chrome, עליך להוסיף את 'fileSystem' למניפסט, כך שאפשר לקבל מהמשתמש הרשאה לאחסן נתונים קבועים.

"permissions": [
  "...",
  "fileSystem"
]

אפשרויות משתמש לבחירת קבצים

המשתמשים מצפים לבחור קבצים באותו אופן שבו הם בוחרים תמיד. לכל הפחות, המפרסם מצפה ל'בחר' 'קובץ' ובוחר הקבצים הרגיל. אם באפליקציה שלך נעשה שימוש נרחב במסירת קבצים, עליך גם להטמיע גרירה ושחרור (ראו בהמשך ואפשר גם לקרוא את המאמר גרירה ושחרור של HTML5 מקורי).

השגת הנתיב של fileEntry

כדי לקבל את הנתיב המלא של הקובץ שהמשתמש בחר, fileEntry, צריך לבצע קריאה אל getDisplayPath():

function displayPath(fileEntry) {
  chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
    console.log(path)
  });
}

הטמעת גרירה ושחרור

אם צריך להטמיע בחירה בשיטת גרירה ושחרור, בקר הקבצים לגרירה ושחרור (dnd.js) הדוגמה filesystem-access היא נקודת התחלה טובה. הבקר יוצר רשומת קובץ מ-DataTransferItem באמצעות גרירה ושחרור. בדוגמה הזו, הערך fileEntry מוגדר שהשמטת פריט.

var dnd = new DnDFileController('body', function(data) {
  var fileEntry = data.items[0].webkitGetAsEntry();
  displayPath(fileEntry);
});

קריאת קובץ

הקוד הבא פותח את הקובץ (לקריאה בלבד) וקורא אותו כטקסט באמצעות אובייקט FileReader. אם המיקום הקובץ לא קיים, נוצרת שגיאה.

var chosenFileEntry = null;

chooseFileButton.addEventListener('click', function(e) {
  chrome.fileSystem.chooseEntry({type: 'openFile'}, function(readOnlyEntry) {

    readOnlyEntry.file(function(file) {
      var reader = new FileReader();

      reader.onerror = errorHandler;
      reader.onloadend = function(e) {
        console.log(e.target.result);
      };

      reader.readAsText(file);
    });
    });
});

כתיבת קובץ

שני תרחישי השימוש הנפוצים לכתיבת קובץ הם "Save" (שמירה). ו'שמירה בשם'. הקוד הבא יוצר writableEntry מ-chosenFileEntry לקריאה בלבד וכותב אליו את הקובץ שנבחר.

 chrome.fileSystem.getWritableEntry(chosenFileEntry, function(writableFileEntry) {
    writableFileEntry.createWriter(function(writer) {
      writer.onerror = errorHandler;
      writer.onwriteend = callback;

    chosenFileEntry.file(function(file) {
      writer.write(file);
    });
  }, errorHandler);
});

הקוד הבא יוצר קובץ חדש עם האפשרות 'שמירה בשם' וכותב את ה-blob החדש באמצעות השיטה writer.write().

chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
    writableFileEntry.createWriter(function(writer) {
      writer.onerror = errorHandler;
      writer.onwriteend = function(e) {
        console.log('write complete');
      };
      writer.write(new Blob(['1234567890'], {type: 'text/plain'}));
    }, errorHandler);
});

שימוש ב-Chrome Sync Filesystem API

באמצעות אחסון קבצים שניתן לסנכרן, ניתן להפעיל אובייקטים של נתונים שהוחזרו באותו אופן כמו הפעלה של אובייקטים מקומיים למערכות קבצים אופליין ב-FileSystem API, אבל עם הסנכרון הנוסף (והאוטומטי) של התהליך הזה ל-Google Drive.

הוספת הרשאה לסנכרון של מערכת הקבצים

כדי להשתמש ב-Sync Filesystem API של Chrome, צריך להוסיף את SyncFileSystem ל מניפסט, כדי לקבל הרשאה מהמשתמש לאחסון ולסנכרון של נתונים קבועים.

"permissions": [
  "...",
  "syncFileSystem"
]

מתחיל אחסון קבצים שניתן לסנכרן

כדי להפעיל אחסון קבצים שניתן לסנכרן באפליקציה, פשוט קוראים ל-syncFileSystem.requestFileSystem. השיטה הזו מחזירה מערכת קבצים ניתנת לסנכרון שמגובה על ידי Google Drive, לדוגמה:

chrome.syncFileSystem.requestFileSystem(function (fs) {
   // FileSystem API should just work on the returned 'fs'.
   fs.root.getFile('test.txt', {create:true}, getEntryCallback, errorCallback);
});

מידע על סטטוס סנכרון קבצים

משתמשים ב-syncFileSystem.getFileStatus כדי לקבל את סטטוס הסנכרון של הקובץ הנוכחי:

chrome.syncFileSystem.getFileStatus(entry, function(status) {...});

ערכי הסטטוס של סנכרון הקבצים יכולים להיות אחד מהערכים הבאים: 'synced', 'pending' או 'conflicting'. 'מסונכרן' פירושו שהקובץ מסונכרן באופן מלא, אין שינויים מקומיים בהמתנה שלא בוצעו סונכרן עם Google Drive. עם זאת, יכולים להיות שינויים בהמתנה ב-Google Drive עדיין לא אוחזרו.

'בהמתנה' המשמעות היא שהקובץ מכיל שינויים בהמתנה שעדיין לא סונכרנו עם Google Drive. אם האפליקציה פועלים באינטרנט, שינויים מקומיים (כמעט) מסתנכרנים באופן מיידי עם Google Drive, האירוע syncFileSystem.onFileStatusChanged מופעל עם הסטטוס 'synced' (מידע נוסף מפורט בהמשך לגבי פרטים נוספים).

ה-syncFileSystem.onFileStatusChanged מופעל כשסטטוס הקובץ משתנה ל- 'conflicting'. 'התנגשות' פירושו שיש שינויים מתנגשים גם באחסון המקומי וגם Google Drive. קובץ יכול להיות במצב הזה רק אם המדיניות לפתרון מחלוקות מוגדרת לערך 'manual' מדיניות ברירת המחדל היא 'last_write_win' וההתנגשויות נפתרות באופן אוטומטי עד מדיניות פשוטה של זכייה בכתיבה אחרונה. ניתן לשנות את המדיניות של המערכת לפתרון התנגשויות על ידי syncFileSystem.setConflictResolutionPolicy.

אם המדיניות לפתרון התנגשויות מוגדרת לערך 'manual' וקובץ מסוים מסתיים במצב 'conflicting', האפליקציה עדיין יכולה לקרוא ולכתוב את הקובץ כקובץ מקומי במצב אופליין, אבל השינויים לא מסתנכרנים והקובץ יישאר מנותק משינויים מרחוק שיבוצעו על ידי לקוחות אחרים עד שההתנגשות הבעיה נפתרה. הדרך הקלה ביותר לפתור התנגשות היא למחוק את הגרסה המקומית של הקובץ או לשנות את שמו. פעולה זו מאלצת לסנכרן את הגרסה המרוחקת, לפתור את המצב הסותר, האירוע onFileStatusChanged מופעל עם הסטטוס 'synced'.

מתבצעת האזנה לשינויים בסטטוס הסנכרון

האירוע syncFileSystem.onFileStatusChanged מופעל כשסטטוס הסנכרון של הקובץ משתנה. לדוגמה, נניח שבקובץ יש שינויים בהמתנה והוא במצב 'בהמתנה' . ייתכן שהאפליקציה במצב אופליין כדי שהשינוי עומד להסתנכרן. כששירות הסנכרון מזהה את בהמתנה לשינוי מקומי ומעלה את השינוי ל-Google Drive, השירות מפעיל את אירוע onFileStatusChanged עם הערכים הבאים: { fileEntry:a fileEntry for the file, status: 'synced', action: 'updated', direction: 'local_to_remote' }.

באופן דומה, ללא קשר לפעילויות המקומיות, שירות הסנכרון עשוי לזהות שינויים מרחוק שבוצעו על ידי לקוח אחר, ומוריד את השינויים מ-Google Drive לאחסון המקומי. אם השלט הרחוק היה שינוי במקרה של הוספת קובץ חדש, מופעל אירוע עם הערכים הבאים: { fileEntry: a fileEntry for the file, status: 'synced', action: 'added', direction: 'remote_to_local' }

אם יש שינויים מתנגשים גם בצד המקומי וגם בצד המרוחק של אותו הקובץ ואם יש התנגשות מדיניות הרזולוציה מוגדרת כ-'manual', סטטוס הקובץ השתנה למצב conflicting, נותק משירות הסנכרון, ולא יסונכרן עד לפתרון ההתנגשות. כאן אם מופעל אירוע עם הערכים הבאים: { fileEntry: a fileEntry for the file, status: 'conflicting', action: null, direction: null }

אפשר להוסיף מאזינים לאירוע הזה שמגיבים לכל שינוי בסטטוס. לדוגמה, אפליקציית נגן המוזיקה של Chrome מאזינה למוזיקה חדשה שמסונכרנת מ-Google Drive, אבל עדיין לא שמיובא לאחסון המקומי של המשתמש אצל לקוח מסוים. כל מוזיקה שנמצאה מסונכרנת עם זה לקוח:

chrome.syncFileSystem.onFileStatusChanged.addListener(function(fileInfo) {
  if (fileInfo.status === 'synced') {
    if (fileInfo.direction === 'remote_to_local') {
      if (fileInfo.action === 'added') {
        db.add(fileInfo.fileEntry);
      } else if (fileInfo.action === 'deleted') {
        db.remove(fileInfo.fileEntry);
      }
    }
  }
});

בדיקת השימוש ב-API

כדי לבדוק את כמות הנתונים שבהם ה-API משתמש, צריך להריץ שאילתה על הספרייה המקומית של האפליקציה בארגז החול או הבייטים של השימוש שהוחזרו על ידי syncFileSystem.getUsageAndQuota:

chrome.syncFileSystem.getUsageAndQuota(fileSystem, function (storageInfo) {
   updateUsageInfo(storageInfo.usageBytes);
   updateQuotaInfo(storageInfo.quotaBytes);
});

אפשר גם לבדוק את האחסון בשירות הקצה העורפי של המשתמש (ב-Google Drive). הקבצים המסונכרנים נשמר בתיקיית Google Drive מוסתרת, מערכת קבצים לסנכרון Chrome. התיקייה לא תופיע ב: 'האחסון שלי' כדי לגשת אליה, על ידי חיפוש שם התיקייה בתיבת החיפוש. (שימו לב: לא בטוח שהפריסה של התיקייה המרוחקת תמשיך להיות תואמת לאחור בין הגרסאות).