2015-03-18 16 views
6

Opracowuję rozszerzenie do Chrome, które będzie zapisywać pliki w folderze pobierania (to nie wszystko, co robię, ale to część, z którą mam problem). Obecnie skupiam się na plikach PDF. Zasadniczo, gdy plik PDF jest otwierany w Chrome, użytkownik może ręcznie zapisać go za pomocą Menu - Zapisz plik jako ... Po prostu próbuję zautomatyzować tę funkcję przy użyciu rozszerzenia, ale nie znalazłem dobrego sposobu na Zrób to.Rozszerzenie Chrome - zapisywanie pliku PDF

Załóżmy, że mogę wykryć, czy bieżąca karta zawiera plik PDF (na podstawie odpowiedzi z pytania this).

Najlepszą rzeczą, jaką zorientowali się tak daleko jest do zainicjowania pobrania:

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

To działa, ale ma 2 wady:

  • plik ma zostać ponownie pobrane, co jest ból, jeśli jest duży. Poza tym plik został już pobrany, więc powinienem móc z niego korzystać.
  • Z jakiegoś powodu nie działa to w przypadku plików otwartych lokalnie ("file: // ..."). Zgłasza NETWORK_INVALID_REQUEST i nie pobiera.

Czy istnieje lepszy sposób na zapisanie pliku?

+0

I przystań znaleźli sposób, za pośrednictwem interfejsu API, aby uzyskać dostęp do plików lokalnych zapisane gdzieś na urządzeniu. Niektóre rozwiązania wskazywały na NPAPI, ale teraz jest to przestarzałe. – Rivero

+0

@Rivero: Właściwie nie potrzebuję dostępu (odczyt) do lokalnego pliku. Po prostu muszę gdzieś zapisać otwarty plik PDF i pobrać lokalizację pliku na dysku, którą może pobrać interfejs API do pobierania. Jednak cierpi z powodu problemów, o których wspomniałem. – vesan

Odpowiedz

1

Adresowanie tylko pliku: // aspekt twojego problemu. Czy twoje rozszerzenie ma uprawnienia dostępu do pliku: //. Aby uzyskać dostęp do twojego rozszerzenia, musisz poprosić o plik: // /, a użytkownik musi ręcznie przyznać ten dostęp na stronie rozszerzeń. Możesz sprawdzić, czy masz wymagane pozwolenie, używając https://developer.chrome.com/extensions/extension#method-isAllowedFileSchemeAccess.

Aby uzyskać więcej informacji na temat uzyskiwania dostępu do pliku: // urls, zobacz stronę Adding file://. permission to chrome extension. Pomocna może być również pomoc w postaci How can I enable my chrome extension in incognito mode?.

Aby zapoznać się z podobną dyskusją (chociaż nie jest to specyficzne dla Twojego przypadku użycia, ponieważ masz już plik PDF), zobacz także https://code.google.com/p/chromium/issues/detail?id=169337.

+0

Wielkie dzięki za linki. Plik: // nie jest tak trudny do rozwiązania, ponieważ celem rozszerzenia jest pobranie aktualnie otwartych plików na dysk. Jeśli jest to plik: //, już tam jest, więc mogę go po prostu użyć. Wolałbym mieć jeden sposób zapisywania http: // i file: // PDF, ale muszę zrobić specjalny przypadek dla pliku: //, ponieważ nie mogę oczekiwać, że nasi użytkownicy będą się bawić w ustawienia. – vesan

3

Note przeglądarki chromu/chrom wydaje dodać embed elementu do document.body wyświetlanie .pdf plików

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

    b) stosując XMLHttpRequest żądania istniejących document, która powinna zwracać pdfdocument jako blob reakcji z cache; zobacz console ->Network ->Headers ->Status Code

  2. Aby umożliwić otwarcie file: w przeglądarkach chrom/chrom, spróbuj z wykorzystaniem wiersza poleceń flagę --allow-access-from-files; patrz How do I make the Google Chrome flag “--allow-file-access-from-files” permanent?


Na .pdfdocument tjsol; Ecma-262.pdf spróbować

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

"XMLHttpRequest' pobieranie pliku z pamięci podręcznej brzmi przydatny, dam to spróbować. Moja jedyna troska dotyczy przypadku, gdy plik PDF jest generowany przez serwer w wyniku żądania POST, GET może nie dać mi tego samego. – vesan