簡體   English   中英

Chrome 擴展程序如何將多個文件保存到用戶指定的目錄?

[英]How can a Chrome extension save many files to a user-specified directory?

我正在開發一個用作內部工具的 Chrome 擴展程序。 其所需的行為是:

  1. 作為頁面操作,在查看某些 Intranet 頁面時啟用地址欄圖標。
  2. 當用戶單擊該圖標時,識別頁面上特定媒體類型(例如 .jpg)的所有文件,以及
  3. 默默地將它們全部保存到用戶本地驅動器上的目錄中。

以前有人問過這個問題,但當時的答案是“ 使用 NPAPI ”,而現在 NPAPI 已被廢棄

那么,目前可用的方法是什么? 我看過的有:

  • chrome.FileSystem API --- 但這不會將文件保存在任何用戶可訪問的位置。 相反,存儲的文件隱藏在未記錄目錄中的混淆名稱后面 用戶要求文件以其原始名稱存儲在可訪問的目錄中。
  • HTML5 下載屬性,通過創建 data: URL 並以編程方式單擊它。 這會為每個文件彈出一個“另存為...”對話框,當單個頁面上有一百個資產時,這是不可接受的。 用戶要求下載文件時,除了單擊單個圖標外,無需進一步交互。
  • Chrome 下載 API ,但僅在 beta 和 dev 渠道中可用。 用戶需要此擴展程序與主流 Chrome 一起使用。
  • 通過創建一個小的 .exe 來使用Native Messaging API ,該 .exe 只是將文件保存到磁盤,然后將 .jpg 作為 blob 傳遞給它。 這看起來很麻煩,我什至不確定如何可靠地將大塊傳遞給這樣的 EXE。

我可以嘗試另一種方法嗎?

你已經做了很多研究。 事實上,如果沒有任何插件或擴展,常規網頁無法寫入用戶的文件系統。 此外,正如您所觀察到的, HTML5 文件系統 API僅提供對虛擬文件系統的訪問。

但是,您將chrome.fileSystem API 與 HTML5 FileSystem API 混淆了。 與 HTML 文件系統 API 不同,Chrome 的fileSystem (應用程序)API 可以直接寫入用戶指定的文件系統(例如~/Documents%USERPROFILE%\\Documents )。

此 API 僅適用於 Chrome應用程序,不適用於擴展程序。 這不是問題,特別是因為您正在開發內部工具,因為您可以安裝應用程序和擴展程序,並使用消息傳遞在擴展程序(頁面操作)和應用程序(文件系統訪問)( 示例)之間進行通信。


關於chrome.downloads :由於您的擴展程序是內部的,您可能可以強制用戶進入 beta/dev 頻道以使用此 API。 此 API 的唯一限制是文件將保存在用戶定義的下載文件夾(的子目錄)中。

編輯: chrome.downloads API 現在可用於所有渠道,包括穩定分支(自 Chrome 31 起)。

恐怕你已經完成了你的功課,這意味着你研究了所有可能的選擇。

實現您想要的最佳方式是(正如您提到的)使用支持本機應用程序並通過本機消息傳遞進行通信。 順便說一句,由於帶寬在 Intranet 上很少成為問題,您可能會發現傳遞資源(例如圖像)URL 並讓應用程序下載並保存它們更簡單。
(是的,這比簡單地開發一個擴展更麻煩,但一個人必須做他們必須做的事情,對吧?)

另一方面,如果您願意為了開發的簡單性而犧牲一點用戶體驗,我建議將 HTML5 好東西(允許您在本地創建和下載文件)與 JS 壓縮庫(例如JSZip )結合起來,所以用戶只需要下載一個 zip 文件(並且只提示一次)。 順便說一句,如果用戶願意,他/她可以選擇始終下載文件而不提示(但您已經知道了)。

使用本機消息應用程序的想法。

本機應用程序很麻煩而且編寫起來很痛苦,因為文檔很差,除非你在兩端都獲得完全正確的 JSON 格式,否則你不會在控制台中看到任何東西,因為 stdin 和 stdout 被接管了。

但是,完成后您會更開心,因為您可以使用標准工具(例如,Windows 資源管理器、十六進制編輯器、TeamViewer...)來查看、移動和刪除文件,以及查看正在發生的事情。 Chrome 的沙盒文件系統可以工作,但現在似乎是一個死胡同(其他瀏覽器都沒有采用)。 沒有人可能會為其開發第三方工具。 當然,一旦一切正常,您可能不需要工具,但在那之前,調試是一場噩夢,因為您需要編寫代碼(以及相當多的代碼)來跟蹤哪些文件位於哪些目錄、文件版本、剩余文件中磁盤空間...

內部(或可能是非內部)使用的另一種解決方案是連接到本地或遠程的 websocket 服務器。

您可以將它放在 background.js 或 content.js 中(使用wss://表示https://

var ws = new WebSocket('ws://echo.websocket.org');
// var ws = new WebSocket('ws://127.0.0.1:9000');
ws.onmessage = function(res) {
    console.log('received data:', res.data);
};
ws.onopen = function() {
    ws.send('hello');
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM