API พื้นที่เก็บข้อมูล

การพัฒนาแอปเกือบทุกด้านจะเกี่ยวข้องกับองค์ประกอบบางอย่างในการส่งหรือรับข้อมูล จากพื้นฐาน คุณควรใช้เฟรมเวิร์ก MVC เพื่อช่วยในการออกแบบและใช้แอป เพื่อให้ข้อมูลแยกจากมุมมองของแอปเกี่ยวกับข้อมูลนั้นโดยสิ้นเชิง (ดูสถาปัตยกรรมMVC)

นอกจากนี้ยังต้องเลือกวิธีจัดการข้อมูลเมื่อแอปออฟไลน์ (ดูส่วนออฟไลน์ก่อน) เอกสารนี้จะแนะนำตัวเลือกการจัดเก็บสำหรับการส่ง รับ และการบันทึกข้อมูลในเครื่องเป็นเวลาสั้นๆ เอกสารที่เหลือจะแสดงวิธีใช้ File System System และ Sync File System API ของ Chrome (โปรดดู fileSystem API และ syncFileSystem API)

ตัวเลือกพื้นที่เก็บข้อมูล

แอปที่อยู่ในแพ็กเกจใช้กลไกหลายอย่างในการส่งและรับข้อมูล สำหรับข้อมูลภายนอก (แหล่งข้อมูล หน้าเว็บ) คุณต้องทราบนโยบายรักษาความปลอดภัยเนื้อหา (CSP) คุณจะใช้ XMLHttpRequests แบบข้ามต้นทาง เพื่อสื่อสารกับเซิร์ฟเวอร์ระยะไกลได้เช่นเดียวกับส่วนขยายของ Chrome นอกจากนี้ คุณยังแยกหน้าภายนอกได้อีกด้วย เพื่อความปลอดภัยของส่วนที่เหลือ (ดูฝังหน้าเว็บภายนอก)

เมื่อบันทึกข้อมูลในเครื่อง คุณจะใช้ Chrome Storage API เพื่อบันทึกข้อมูลสตริงและ IndexedDB จำนวนเล็กน้อยเพื่อบันทึกข้อมูลที่มีโครงสร้างได้ เมื่อใช้ IndexedDB คุณสามารถเก็บออบเจ็กต์ JavaScript ไว้ในที่เก็บออบเจ็กต์และใช้ดัชนีของสโตร์เพื่อค้นหาข้อมูล (ดูข้อมูลเพิ่มเติมได้ที่บทแนะนำรายการสิ่งที่ต้องทำอย่างง่ายของ HTML5 Rock) สำหรับข้อมูลประเภทอื่นๆ ทั้งหมด เช่น ข้อมูลไบนารี ให้ใช้ Filesystem และ Sync Filesystem API

Filesystem and Sync Filesystem API ของ Chrome จะช่วยขยาย HTML5 FileSystem API Filesystem API ของ Chrome ช่วยให้แอปสร้าง อ่าน ไปยังส่วนต่างๆ และเขียนลงในส่วนที่แซนด์บ็อกซ์ในระบบไฟล์ในเครื่องของผู้ใช้ได้ ตัวอย่างเช่น แอปแชร์รูปภาพสามารถใช้ Filesystem API เพื่ออ่านและเขียนรูปภาพที่ผู้ใช้เลือก

Sync Filesystem API ของ Chrome ช่วยให้แอปบันทึกและซิงค์ข้อมูลใน Google ไดรฟ์ของผู้ใช้ได้ เพื่อให้มีข้อมูลเดียวกันในไคลเอ็นต์ต่างๆ เช่น แอปเครื่องมือแก้ไขข้อความที่มีระบบคลาวด์จะซิงค์ไฟล์ข้อความใหม่กับบัญชี Google ไดรฟ์ของผู้ใช้ได้โดยอัตโนมัติ เมื่อผู้ใช้เปิดเครื่องมือแก้ไขข้อความในไคลเอ็นต์ใหม่ Google ไดรฟ์จะพุชไฟล์ข้อความใหม่ไปยังอินสแตนซ์ดังกล่าวของเครื่องมือแก้ไขข้อความ

การใช้ Chrome Filesystem API

การเพิ่มสิทธิ์ระบบไฟล์

หากต้องการใช้ File System API ของ Chrome คุณต้องเพิ่มสิทธิ์ "fileSystem" ในไฟล์ Manifest เพื่อให้คุณสามารถขออนุญาตจากผู้ใช้ในการจัดเก็บข้อมูลถาวร

"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);
    });
    });
});

การเขียนไฟล์

กรณีการใช้งานทั่วไปสำหรับการเขียนไฟล์มี 2 กรณีคือ "บันทึก" และ "บันทึกเป็น" โค้ดต่อไปนี้จะสร้าง 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 ไดรฟ์

การเพิ่มสิทธิ์ระบบไฟล์การซิงค์

หากต้องการใช้ Sync Filesystem API ของ Chrome คุณต้องเพิ่มสิทธิ์ "syncFileSystem" ในไฟล์ Manifest เพื่อขออนุญาตจากผู้ใช้ในการจัดเก็บและซิงค์ข้อมูลถาวร

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

กำลังเริ่มต้นพื้นที่เก็บข้อมูลไฟล์ที่ซิงค์ได้

หากต้องการเริ่มพื้นที่เก็บไฟล์ที่ซิงค์ได้ในแอป เพียงเรียกใช้ syncFileSystem.requestFileSystem วิธีการนี้จะแสดงผลระบบไฟล์ที่ซิงค์ได้ซึ่งสนับสนุนโดย Google ไดรฟ์ เช่น

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 ไดรฟ์ อย่างไรก็ตาม อาจมีการเปลี่ยนแปลงที่รอดำเนินการในฝั่ง Google ไดรฟ์ที่ยังไม่ได้ดึงข้อมูล

"รอดำเนินการ" หมายถึง ไฟล์มีการเปลี่ยนแปลงที่รอดําเนินการ แต่ยังไม่ได้ซิงค์กับ Google ไดรฟ์ หากแอปทำงานออนไลน์ การเปลี่ยนแปลงในเครื่อง (เกือบ) จะซิงค์กับ Google ไดรฟ์ทันที และเหตุการณ์ syncFileSystem.onFileStatusChanged จะเริ่มทำงานโดยมีสถานะ 'synced' (ดูรายละเอียดเพิ่มเติมด้านล่าง)

syncFileSystem.onFileStatusChanged จะเริ่มทำงานเมื่อสถานะของไฟล์เปลี่ยนเป็น 'conflicting' "ขัดแย้ง" หมายความว่ามีการเปลี่ยนแปลงที่ขัดแย้งกันทั้งในพื้นที่เก็บข้อมูลในเครื่องและ Google ไดรฟ์ ไฟล์จะอยู่ในสถานะนี้ได้ก็ต่อเมื่อตั้งค่านโยบายการแก้ไขความขัดแย้งเป็น 'manual' นโยบายเริ่มต้นคือ 'last_write_win' และความขัดแย้งจะได้รับการแก้ไขโดยอัตโนมัติด้วยนโยบายการเขียนครั้งสุดท้ายแบบพื้นฐาน นโยบายการแก้ไขความขัดแย้งของระบบจะเปลี่ยนแปลงได้โดย syncFileSystem.setConflictResolutionPolicy

หากตั้งค่านโยบายการแก้ไขความขัดแย้งเป็น 'manual' และไฟล์ส่งผลให้เกิดสถานะ 'conflicting' แอปจะยังอ่านและเขียนไฟล์เป็นไฟล์ออฟไลน์ในเครื่องได้ แต่ระบบจะไม่ซิงค์การเปลี่ยนแปลงและจะแยกไฟล์ออกจากการเปลี่ยนแปลงจากระยะไกลที่ทำในไคลเอ็นต์อื่นๆ จนกว่าความขัดแย้งจะได้รับการแก้ไข วิธีที่ง่ายที่สุดในการแก้ไขข้อขัดแย้งคือการลบหรือเปลี่ยนชื่อไฟล์ในเครื่อง ซึ่งจะบังคับให้ซิงค์เวอร์ชันระยะไกล แก้ไขสถานะที่ขัดแย้งกัน และเหตุการณ์ onFileStatusChanged จะเริ่มทำงานด้วยสถานะ 'synced'

กำลังฟังการเปลี่ยนแปลงสถานะที่ซิงค์

เหตุการณ์ syncFileSystem.onFileStatusChanged จะเริ่มทำงานเมื่อสถานะการซิงค์ของไฟล์มีการเปลี่ยนแปลง ตัวอย่างเช่น สมมติว่าไฟล์มีการเปลี่ยนแปลงที่รอดำเนินการและอยู่ในสถานะ "รอดำเนินการ" แอปอาจอยู่ในสถานะออฟไลน์ ดังนั้นระบบกำลังจะซิงค์การเปลี่ยนแปลง เมื่อบริการซิงค์ตรวจพบการเปลี่ยนแปลงในเครื่องที่รอดำเนินการและอัปโหลดการเปลี่ยนแปลงไปยัง Google ไดรฟ์ บริการจะเริ่มเหตุการณ์ onFileStatusChanged ด้วยค่าต่อไปนี้ { fileEntry:a fileEntry for the file, status: 'synced', action: 'updated', direction: 'local_to_remote' }

ในทำนองเดียวกัน ไม่ว่ากิจกรรมในเครื่องจะเป็นอย่างไร บริการซิงค์อาจตรวจพบการเปลี่ยนแปลงระยะไกลที่ไคลเอ็นต์อื่นทำ และดาวน์โหลดการเปลี่ยนแปลงจาก Google ไดรฟ์ไปยังพื้นที่เก็บข้อมูลในเครื่อง หากการเปลี่ยนแปลงระยะไกลมีไว้เพื่อเพิ่มไฟล์ใหม่ เหตุการณ์ที่มีค่าต่อไปนี้จะเริ่มทำงาน: { 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 }

คุณสามารถเพิ่ม Listener สำหรับกิจกรรมนี้ที่ตอบสนองต่อการเปลี่ยนแปลงของสถานะ เช่น แอป Chrome Music Player จะฟังเพลงใหม่ๆ ที่ซิงค์จาก Google ไดรฟ์ แต่ยังไม่ได้นำเข้าไปยังพื้นที่เก็บข้อมูลในเครื่องของผู้ใช้ในไคลเอ็นต์หนึ่งๆ ทุกเพลงที่พบจะซิงค์กับ ไคลเอ็นต์ ดังนี้

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 ไดรฟ์) ได้ด้วย ไฟล์ที่ซิงค์จะบันทึกลงในโฟลเดอร์ Google ไดรฟ์ที่ซ่อนอยู่ ซึ่งก็คือ Chrome Syncable FileSystem โฟลเดอร์นี้จะไม่แสดงใน รายการ "ไดรฟ์ของฉัน" แต่สามารถเข้าถึงได้ด้วยการค้นหาชื่อโฟลเดอร์ในช่องค้นหา (โปรดทราบว่าไม่รับประกันว่าเลย์เอาต์ของโฟลเดอร์ระยะไกลจะยังคงเข้ากันได้แบบย้อนหลังระหว่างแต่ละรุ่น)