Chrome extension - save PDF file

I am developing a Chrome extension that will save files in a download folder (which is not all that it does, but in the part that I'm having problems with). Now I am focusing on PDF files. Basically, when a PDF opens in Chrome, the user can manually save it using Menu - Save File As ..., I'm just trying to automate this function with the extension, but I did not find a good way to do this.

Let's say I can determine if there is a PDF file in the current tab (based on the answers from this question).

The best thing I have guessed so far is to start the 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 must be reloaded, which hurts if it is large. Also, the file is already uploaded, so I have to use it.
  • For some reason this does not work with files opened locally ("file: // ..."). It issues NETWORK_INVALID_REQUEST and does not load.

Is there a better way to save the file?

+6
source share
2 answers

Note that chrome / chrome browsers add document.body to the embed element to display .pdf files

  • a) pdf detection using window.location.href , document.querySelectorAll("embed")[0].type ;

    b) using XMLHttpRequest to query an existing document , which should return a pdf document as a blob response, from cache ; see consoleNetworkHeadersStatus Code

  • To allow opening file: protocol in chromium / chrome browsers, try using the command line flag --allow-access-from-files ; see How to make the Google Chrome flag "-allow-file-access-from-files" permanent?


At .pdf document , i.e. 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(); }; 
+3
source

File-only addressing: // aspect of your problem. Your extension has permission to access the file: //. To have access to your extension, you need to ask the file: ///, and the user must manually provide this access from the extensions page. You can check if you have the required permission using https://developer.chrome.com/extensions/extension#method-isAllowedFileSchemeAccess .

See Adding a file: //. permission to the chrome extension for more information on accessing the file: // urls. You can also find How do I enable the chrome extension in incognito mode? .

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

+1
source

Source: https://habr.com/ru/post/983947/


All Articles