將檔案與 PWA 關聯

在裝置上,檔案通常與應用相關聯。因此,當用戶開啟檔案時,作業系統會啟動相應的應用並將檔案傳遞給它。例如,HTML 檔案通常在 Web 瀏覽器中開啟,文字檔案在文字編輯器中開啟,影片在影片播放器中開啟。

漸進式 Web 應用可以參與此功能,因此當用戶單擊特定型別的檔案時,PWA 可能會被啟動來處理它。

新增檔案處理支援包括兩個部分:

  • 使用 file_handlers web app manifest 成員宣告對某些檔案型別的支援。
  • 使用 LaunchQueue 介面處理檔案。

注意:目前此功能僅適用於基於 Chromium 的瀏覽器,並且僅適用於桌面作業系統。

宣告對檔案型別的支援

要宣告對特定檔案型別的支援,請在 manifest 檔案中包含 file_handlers 成員。

file_handlers 成員是一個檔案處理程式物件的陣列。每個檔案處理程式物件都有兩個必需屬性:actionaccept

  • accept 屬性包含處理程式知道如何處理的檔案的 MIME 型別和相關副檔名。
  • action 屬性是一個 URL,當用戶開啟檔案時,PWA 將導航到該 URL。此頁面必須在 PWA 的範圍內。

下面的 manifest 檔案包含一個帶有單個處理程式的 file_handlers 成員,該處理程式可以處理 JPEGPNG 檔案,並且當用戶單擊其中一個檔案時,它將導航到 PWA 的根頁面。

json
{
  "name": "File handling demo",
  "icons": [
    {
      "src": "icons/lightbulb.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "/",
  "display": "standalone",
  "file_handlers": [
    {
      "action": "/",
      "accept": {
        "image/jpeg": [".jpg", ".jpeg"],
        "image/png": [".png"]
      }
    }
  ]
}

使用此 manifest,一旦安裝了 PWA,當用戶開啟這些型別的檔案時,它可能會被開啟。

通常不止一個應用可以開啟任何給定型別的檔案,因此作業系統通常提供一項功能,允許使用者選擇使用哪個應用開啟檔案,並設定預設處理程式。例如,在 macOS 上,使用者可以右鍵單擊檔案,選擇“獲取資訊”,並在生成的對話方塊中配置預設處理程式

Selecting the default handler on macOS

請求許可權

當瀏覽器首次將啟動您的 PWA 來處理使用者開啟的一個或多個檔案時,它會要求使用者確認他們是否要使用您的 PWA 開啟它。例如,Chrome 對話方塊如下所示

Chrome warning dialog for launching PWA to handle a file

處理檔案

當瀏覽器啟動您的 PWA 並導航到您在 file_handlers manifest 成員的 action 屬性中指定的頁面時,您需要執行一些程式碼來處理檔案。此程式碼將在 action 屬性中指定的頁面中執行。

這裡的關鍵介面是 LaunchQueue,它作為全域性 Window 物件的屬性提供。

LaunchQueue 介面有一個方法,setConsumer(),它接受一個回撥函式作為引數,當瀏覽器啟動 PWA 並帶有一個或多個要處理的檔案時,該回調函式將被呼叫。

回撥函式會傳遞一個 LaunchParams 物件,該物件包含一個 files 屬性,其中包含一個 FileSystemHandle 物件的陣列,每個物件代表使用者開啟的一個檔案。

例如,下面的程式碼讀取檔案並將其內容分配給 <img> 元素,然後將其新增到頁面中

js
const imageContainer = document.querySelector("#container");

if ("launchQueue" in window) {
  launchQueue.setConsumer(async (launchParams) => {
    for (const file of launchParams.files) {
      const img = document.createElement("img");
      img.src = URL.createObjectURL(await file.getFile());
      imageContainer.appendChild(img);
    }
  });
}

請注意,程式碼在使用 launchQueue 之前會檢查它是否存在,以確保應用在不支援該 API 的瀏覽器中也能正常執行。

另見