Chrome 扩展程序:如何在磁盘上保存文件

IT技术 javascript google-chrome google-chrome-extension
2021-01-13 12:12:11

我目前正在为谷歌浏览器创建一个扩展程序,它可以将所有图像或图像链接保存在硬盘驱动器上。

问题是我不知道如何使用 JS 或 Google Chrome 扩展 API 将文件保存在磁盘上。

你有什么想法吗?

6个回答

您可以使用HTML5 文件系统功能使用下载API写入磁盘这是将文件下载到磁盘的唯一方法,而且它是有限的。

你可以看看 NPAPI 插件。另一种方法是简单地通过 XHR POST 向外部网站发送请求,然后通过另一个 GET 请求检索文件,该请求将显示为保存文件对话框。

例如,对于我的浏览器扩展My Hangouts,我创建了一个实用程序,用于将照片从 HTML5 Canvas 直接下载到磁盘。你可以看看这里的代码capture_gallery_downloader.js这样做的代码是:

var url = window.webkitURL || window.URL || window.mozURL || window.msURL;
var a = document.createElement('a');
a.download = 'MyHangouts-MomentCapture.jpg';
a.href = url.createObjectURL(dataURIToBlob(data.active, 'jpg'));
a.textContent = 'Click here to download!';
a.dataset.downloadurl = ['jpg', a.download, a.href].join(':');

如果您想要在 HTML5 中将 URI 转换为 Blob 的实现,我是这样做的:

/**
 * Converts the Data Image URI to a Blob.
 *
 * @param {string} dataURI base64 data image URI.
 * @param {string} mimetype the image mimetype.
 */
var dataURIToBlob = function(dataURI, mimetype) {
  var BASE64_MARKER = ';base64,';
  var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
  var base64 = dataURI.substring(base64Index);
  var raw = window.atob(base64);
  var rawLength = raw.length;
  var uInt8Array = new Uint8Array(rawLength);

  for (var i = 0; i < rawLength; ++i) {
    uInt8Array[i] = raw.charCodeAt(i);
  }

  var bb = new this.BlobBuilder();
  bb.append(uInt8Array.buffer);
  return bb.getBlob(mimetype);
};

然后在用户单击下载按钮后,它将使用“下载”HTML5 文件 API 将 blob URI 下载到文件中。

我同意马克斯。它会延迟发布,因为它将被手动审核。如果您有一个外部服务器,您可以在扩展程序中提供访问权限,并通过 POST 上传数据并通过带有适当标头的 GET 将其取回,那将是最好的。
2021-03-17 12:12:11
它是否允许我将标记的简短单词保存到本地硬盘上的文件中?
2021-03-17 12:12:11
请注意,如果您计划将扩展程序上传到 Google 的图库,使用 NPAPI 会延迟您的发布,以便他们进行长时间的审核,甚至可能最终不会被接受。
2021-03-29 12:12:11
这不是我们第一次在 NPAPI 上重定向我。我会看一下。谢谢您的帮助
2021-04-03 12:12:11

我一直希望为自己制作一个 chrome 扩展程序来批量下载图像。然而,每次我感到沮丧时,因为唯一看似适用的选项是 NPAPI,chrome 和 firefox 似乎都不再希望支持它。

我建议那些仍然想要实现“save-file-on-disk”功能的人看看这篇Stackoverflow 帖子,这篇帖子下面的评论对我有很大帮助。

现在从 chrome 31+ 开始,chrome.downloadsAPI 变得稳定了。我们可以使用它以编程方式下载文件。如果用户没有ask me before every download在chrome设置中设置高级选项,我们可以在不提示用户确认的情况下保存文件!

这是我使用的(在扩展的背景页面):

    // remember to add "permissions": ["downloads"] to manifest.json
    // this snippet is inside a onMessage() listener function
    var imgurl = "https://www.google.com.hk/images/srpr/logo11w.png";
    chrome.downloads.download({url:imgurl},function(downloadId){
        console.log("download begin, the downId is:" + downloadId);
    });

虽然很遗憾 chrome 仍然没有Event在下载完成时提供chrome.downloads.download下载begin成功时调用的回调函数(未完成时)

官方文档大约chrome.downloads在这里

这不是我对解决方案的最初想法,但我在这里发布希望它对某人有用。

@Pacerier 这是调用下载架子,当我写答案时,我记得我必须手动禁用架子显示在高级选项页面中。我做了一些搜索,我发现了这个:你可能很有趣。setShelfEnabled chrome.downloads.setShelfEnabled(boolean enabled)启用或禁用与当前浏览器配置文件关联的每个窗口底部的灰色架子。只要至少有一个分机禁用了搁板,它就会被禁用。在至少一个其他扩展已禁用时启用架子将通过 runtime.lastError 返回错误。
2021-03-20 12:12:11
不知道 2014 年的情况,但截至今天,可以收听onChanged带有state可以告知下载状态对象事件(例如“完成”)。
2021-03-23 12:12:11
@Allan,Re“我们可以在不提示用户确认的情况下保存文件”;但是当你开始向用户的机器写入文件时,底部的“下载栏”不会被打开吗?有没有办法默默地做到这一点?(例如,如果您在后台向用户机器写入 50 个文件)
2021-03-29 12:12:11

据我所知,没有办法将文件静默保存到用户的驱动器中,这似乎是您希望做的。我认为您可以使用以下内容要求一次保存一个文件(每次提示用户):

function saveAsMe (filename)
{
document.execCommand('SaveAs',null,filename)
}

如果您只想提示用户一次,您可以静默抓取所有图像,将它们压缩成一个包,然后让用户下载。这可能意味着对所有文件执行 XmlHttpRequest,用 Javascript 压缩它们,将它们上传到暂存区,然后询问用户是否要下载 zip 文件。听起来很荒谬,我知道。

浏览器中有本地存储选项,但据我所知,它们仅供开发人员在沙箱内使用。(例如 Gmail 离线缓存。)查看 Google 最近发布的类似这样的公告

考虑使用HTML5文件系统功能,可以使用 Javascript 写入文件。

Google 网上商店
Github

如果这里有人仍然感兴趣,我做了一个扩展,可以做这样的事情。它使用 XMLHTTPRequest 来获取对象(在本例中假定为图像),然后创建指向它的 ObjectURL、指向该 ObjectUrl 的链接,然后单击假想的链接。

第一个链接点击 404
2021-04-02 12:12:11