2016-07-12 64 views
0

我在Chrome擴展中有三個以下代碼的失敗版本,它試圖攔截點擊指向​​PDF文件的鏈接,獲取該文件,將其轉換爲base64,然後將其記錄下來。但是恐怕我對真正的二進制格式和編碼知之甚少,所以我非常吝嗇。如何在瀏覽器中正確地將pdf文件轉換爲base64?

var links = document.getElementsByTagName("a"); 

function transform(blob) { 
    return btoa(String.fromCharCode.apply(null, new Uint8Array(blob))); 
}; 

function getlink(link) { 
    var x = new XMLHttpRequest(); 
    x.open("GET", link, true); 
    x.responseType = 'blob'; 
    x.onload = function(e) { 
     console.log("Raw response:"); 
     console.log(x.response); 
     console.log("Direct transformation:"); 
     console.log(btoa(x.response)); 
     console.log("Mysterious thing I got from SO:"); 
     console.log(transform(x.response)); 
     window.location.href = link; 
    }; 

    x.onerror = function (e) { 
     console.error(x.statusText); 
    }; 

    x.send(null); 
}; 

for (i = 0, len = links.length; i < len; i++) { 
    var l = links[i] 
    l.addEventListener("click", function(e) { 
     e.preventDefault(); 
     e.stopPropagation(); 
     e.stopImmediatePropagation(); 
     getlink(this.href); 
    }, false); 
}; 

1版不具備呼叫x.responseType,或調用transform。這是我原來的,天真的實施。它拋出一個錯誤:「要編碼的字符串包含Latin1範圍之外的字符。」

谷歌搜索該誤差後,我發現this prior SO,這表明在分析的圖像:

  1. 的響應類型需要被設置到斑點。所以這段代碼就是這樣。
  2. 有一些奇怪的線條,我不知道它在做什麼:String.fromCharCode.apply(null, new Uint8Array(blob))

因爲我對二進制格式一無所知,所以我猜測,可能愚蠢的是,使PDF base64與製作一些隨機圖像格式base64是一樣的。所以,在SO傳統中,我複製了我不太瞭解的代碼。分階段。

版本2的代碼只是將響應類型設置爲blob,但沒有嘗試第二次轉換。代碼工作,並記錄了一些看起來像base64字符串的東西,但顯然不正確字符串。它的完整記錄:

W29iamVjdCBCbG9iXQ==

這只是愚蠢的錯誤。對於一個46k的pdf文件來說,它顯然太短了,我從命令行使用python創建的參考base64編碼要長得多,正如人們所期望的那樣。

代碼的版本3然後也使用stringFromCharCode和所有其他的,我把它推入transform函數的神祕轉換。

但是,這並不記錄任何內容---控制檯中的適當位置出現空白行。沒有錯誤,沒有廢話輸出,只是一個空白行。

我知道我從之前的測試中得到了正確的文件。此外,記錄原始響應對象的調用產生Blob {size: 45587, type: "application/pdf"},這是我正在嘗試使用的pdf的正確文件大小,所以blob實際上包含它在進入瀏覽器時的內容。

我正在使用並且只需要支持當前版本的chrome。

有人能告訴我我做錯了什麼嗎?

謝謝!

回答

0

我想我已經找到了我自己的解決方案。響應類型需要爲arraybuffer而不是blob

1

如果你只需要支持現代瀏覽器,你應該也可以使用FileReader#readAsDataURL

,將讓你做這樣的事情:

var reader = new FileReader(); 
reader.addEventListener("load", function() { 
    console.log(reader.result); 
}, false); 
// The function accepts Blobs and Files 
reader.readAsDataURL(x.response); 

這將記錄一個data URI,其中將包含您的base64數據。

+0

哇!這很酷 - 我可能不得不收回對JS的咆哮,我剛剛在評論中寫到這個擴展的演示版本。也許。 https://github.com/paultopia/scrape-pdf/commit/5b47232893ddbf19745e7a825135a306b8d5355e –

+0

@PaulGowder你讓我笑了起來。我們都去過那裏。如果這不適合你,請隨時告訴我們,我們會看看我們還能做些什麼。 –

相關問題