【问题标题】:Chrome extension - saving PDF fileChrome 扩展 - 保存 PDF 文件
【发布时间】:2015-05-20 19:24:17
【问题描述】:

我正在开发一个 Chrome 扩展程序,它将文件保存到下载文件夹(这还不是全部,但这是我遇到问题的部分)。现在我专注于PDF文件。基本上,当在 Chrome 中打开 PDF 时,用户可以使用 Menu -> Save File As 手动保存它...,我只是尝试使用扩展程序自动执行此功能,但我还没有找到一个好的方法来做到这一点。

假设我可以检测当前选项卡中是否有 PDF 文件(基于来自 this 问题的答案)。

到目前为止,我认为最好的办法是启动下载:

chrome.downloads.download({
    url: tabs[0].url, saveAs: false,
    filename: "my file", /* This will be some unique autogenerated identifier */
    conflictAction: "overwrite"
});

这可行,但有两个缺点:

  • 文件必须重新下载,如果文件很大,这会很痛苦。另外,文件已经下载好了,应该可以用了。
  • 由于某种原因,这不适用于本地打开的文件(“file://...”)。它会抛出 NETWORK_INVALID_REQUEST 并且不会下载。

有没有更好的方法来保存文件?

【问题讨论】:

  • 我还没有找到通过 API 访问保存在设备上某处的本地文件的方法。一些解决方案指向 NPAPI,但现在已弃用。
  • @Rivero:我实际上不需要访问(读取)本地文件。我只需要将打开的 PDF 保存在某个地方并获取驱动器上的文件位置,下载 API 可以做到这一点。但是,它存在我提到的问题。

标签: javascript google-chrome pdf google-chrome-extension


【解决方案1】:

注意,铬/铬浏览器似乎将 embed 元素附加到 document.body 以显示 .pdf 文件

  1. a) 利用window.location.hrefdocument.querySelectorAll("embed")[0].type 检测pdf

    b) 利用XMLHttpRequest 请求现有的document,它应该从cache 返回pdf document 作为blob 响应;见console -> Network -> Headers -> Status Code

  2. 要允许在 chromium / chrome 浏览器中打开 file: protocol,请尝试使用命令行标志 --allow-access-from-files;见How do I make the Google Chrome flag “--allow-file-access-from-files” permanent?


.pdf document ,即; Ecma-262.pdf试试

// check if `document` is `pdf`
if (/pdf/i.test(window.location.href.slice(-3)) 
    || document.querySelectorAll("embed")[0].type === "application/pdf") {
    var xhr = new XMLHttpRequest();
    // load `document` from `cache`
    xhr.open("GET", "", true); 
    xhr.responseType = "blob";
    xhr.onload = function (e) {
        if (this.status === 200) {
            // `blob` response
            console.log(this.response);
            var file = window.URL.createObjectURL(this.response);
            var a = document.createElement("a");
            a.href = file;
            a.download = this.response.name 
                        || document.querySelectorAll("embed")[0].src
                           .split("/").pop();
            document.body.appendChild(a);
            a.click();
            // remove `a` following `Save As` dialog, 
            // `window` regains `focus`
            window.onfocus = function () {                     
                Array.prototype.forEach.call(document.querySelectorAll("a")
                , function (el) {
                    document.body.removeChild(el)
                })
            }
        };
    };
    xhr.send();
};

【讨论】:

  • XMLHttpRequest 从缓存中获取文件听起来很有用,我会尝试一下。我唯一担心的是,当 PDF 由服务器作为 POST 请求的结果生成时,GET 可能不会给我同样的东西。
【解决方案2】:

仅解决问题的 file:// 方面。您的扩展程序是否有权访问 file://.为了访问您的扩展程序,两者都需要请求 file:/// 并且用户必须从扩展程序页面手动授予此访问权限。您可以使用https://developer.chrome.com/extensions/extension#method-isAllowedFileSchemeAccess 检查您是否拥有必要的权限。

有关访问 file:// url 的更多信息,请参阅 Adding file://. permission to chrome extension。您可能还会发现 How can I enable my chrome extension in incognito mode? 很有帮助。

有关相关讨论(尽管不是针对您的用例,因为您已有 PDF 文件),另请参阅 https://code.google.com/p/chromium/issues/detail?id=169337

【讨论】:

  • 非常感谢您的链接。 file://其实并没有那么难解决,因为扩展的目的是为了获取当前打开的文件到磁盘。如果是file://,它已经存在了,所以我可以使用它。我希望有一种方法来保存 http:// 和 file:// PDF,但我必须为 file:// 设置一个特殊情况,因为我不能指望我们的用户会乱来设置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 2015-07-02
  • 2016-03-27
  • 2023-04-07
  • 1970-01-01
相关资源
最近更新 更多