最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Chrome extension - saving PDF file - Stack Overflow

programmeradmin4浏览0评论

I'm developing a Chrome extension that will save files to the downloads folder (that's not all it's doing, but that's the part I have trouble with). Right now I'm focusing on PDF files. Basically, when a PDF is opened in Chrome, the user can manually save it using Menu -> Save File As ..., I'm just trying to automate this functionality using the extension, but I haven't found a good way to do it.

Let's say I can detect if the current tab has a PDF file in it (based on answers from this question).

The best thing I have figured out so far is to initiate a download:

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

This works but has 2 drawbacks:

  • The file has to be re-downloaded, which is a pain if it's large. Besides, the file has been downloaded already so I should be able to use it.
  • For some reason this doesn't work with files opened locally ("file://..."). It throws a NETWORK_INVALID_REQUEST and doesn't download.

Is there a better way to save the file?

I'm developing a Chrome extension that will save files to the downloads folder (that's not all it's doing, but that's the part I have trouble with). Right now I'm focusing on PDF files. Basically, when a PDF is opened in Chrome, the user can manually save it using Menu -> Save File As ..., I'm just trying to automate this functionality using the extension, but I haven't found a good way to do it.

Let's say I can detect if the current tab has a PDF file in it (based on answers from this question).

The best thing I have figured out so far is to initiate a download:

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

This works but has 2 drawbacks:

  • The file has to be re-downloaded, which is a pain if it's large. Besides, the file has been downloaded already so I should be able to use it.
  • For some reason this doesn't work with files opened locally ("file://..."). It throws a NETWORK_INVALID_REQUEST and doesn't download.

Is there a better way to save the file?

Share Improve this question edited Oct 25, 2018 at 9:02 kaizer1v 9088 silver badges21 bronze badges asked Mar 18, 2015 at 5:35 vesanvesan 3,36925 silver badges36 bronze badges 2
  • I havent found a way, through an API, to access the local files saved somewhere on your device. Some solutions pointed to NPAPI, but this is now deprecated. – Rivero Commented Mar 19, 2015 at 20:02
  • @Rivero: I actually don't need to access (read) the local file. I just need to save the opened PDF somewhere and get the file location on the drive, which the download API can do. However, it suffers from the problems I mentioned. – vesan Commented Mar 19, 2015 at 22:06
Add a ment  | 

2 Answers 2

Reset to default 3 +50

Note, chromium / chrome browsers appear to append embed element to document.body to display .pdf files

  1. a) detecting pdf utilizing window.location.href , document.querySelectorAll("embed")[0].type;

    b) utilizing XMLHttpRequest to request existing document, which should return pdf document as blob response, from cache; see console -> Network -> Headers -> Status Code

  2. To allow opening file: protocol at chromium / chrome browsers, try utilizing mand line flag --allow-access-from-files; see How do I make the Google Chrome flag “--allow-file-access-from-files” permanent?


At .pdf document , i.e.g; Ecma-262.pdf try

// 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();
};

Addressing only the file:// aspect of your problem. Does your extension have permission to access file://. In order to have access your extension both needs to ask for file:/// and user has to manually grant this access from the extensions page. You can check if you have the requisite permission using https://developer.chrome./extensions/extension#method-isAllowedFileSchemeAccess.

See Adding file://. permission to chrome extension for more information about accessing file:// urls. You may also find How can I enable my chrome extension in incognito mode? helpful.

For a related discussion (although not specific for your use case since you already have a PDF file), also see https://code.google./p/chromium/issues/detail?id=169337.

发布评论

评论列表(0)

  1. 暂无评论