2011-06-04 51 views
2

我正在用JavaScript做一些非常邪惡的事情,而且我遇到了一個奇怪的問題。當base64 null後跟= =時,HTML5數據URI失敗

我正在創建填充靜態大小的緩衝區的二進制數據。如果內容未填充緩衝區,則其餘部分填充空字符。

下一步是轉換爲base64。

大小(字節)不總是3的倍數,所以我可能需要添加填充到最後。緩衝區中的最後一個字節總是空(實際上,它大約是一個空值)。

當我將它轉換爲Firefox和Chrome上的base64時,當我有一個尾隨'='時,我得到一個ERR_INVALID_URL,但是當我不這樣做時它會下載正常。

例如:

var url = "data:application/octet-stream;base64,"; 

window.open(url + "AAAA"); // works 
window.open(url + "AAAA="); // doesn't work 
window.open(url + "icw="); // works 

我的文件的工作,但他們不符合規格。

這是無效的base64有一個原因嗎?更重要的是,這是一個錯誤還是規範的一部分?

編輯:

我已經張貼的答案,讓一些Firefox和Chrome之間的奇怪的現象。有誰知道該標準指定了什麼?或者它是導致碎片的鬆散規格之一?如果可能的話,我想要一些確定性的東西。

+0

我添加了另一個工作(非空字符串與等號)。 – tjameson 2011-06-04 17:28:26

+0

哇,可以肯定的是,有很多關於數據URL和編碼的混淆和矛盾的信息。 – Pointy 2011-06-04 17:49:08

回答

5

填充字符=用於填充四個代碼字符的倍數。由於輸入的每三個字節都映射到四個字節的輸出上,因此不是三的倍數的輸入字節數需要填充(其餘一個字節需要==,剩餘兩個字節需要=)。

在你的情況下AAAA已經是一個有效的代碼字,不需要填充。

+0

所以,AAAA是3個空字節。如果我有4個空字節呢? – tjameson 2011-06-04 17:22:56

+0

@tjameson:那會是'AAAAAA =='。 – Gumbo 2011-06-04 17:28:10

+0

你確定在「base64url」編碼中有需要填充字符嗎?我無法找到任何決定性的方法或其他。 – Pointy 2011-06-04 17:46:09

2

你爲什麼會想象在字符串的末尾添加「=」字符會起作用?這在base64中不是一個有效的字符。

字符集是大寫和小寫字母;數字;和「+」和「/」。因此,任何其他內容在base64字符串中都是無效的。

編輯 —以及針對URL似乎不是「+」和「/」你用「 - 」和「_」(在字符集位置62和63)。

編輯更多 —這是一個非常令人困惑的話題,因爲存在着不同的,顯然權威但矛盾的信息來源。例如,the Mozilla description of the data URL scheme沒有提到使用「文件名友好」替代編碼。 IETF數據網址RFC也一樣。但是,其他IETF文檔清楚地討論並指定了用「 - 」和「_」替換有問題的(用於文件名)「+」和「/」的變體。

因此,我宣佈自己是無知的:-) Gumbo可能是正確的,你得到的抱怨是關於不正確的填充(即沒有填充實際上是必要時的填充)。

+0

它被用作填充。 http://en.wikipedia.org/wiki/Base64#Padding – tjameson 2011-06-04 17:14:23

+1

在這個相同的頁面上,您可以發現在URL中使用base64符號中沒有填充字符。 – Pointy 2011-06-04 17:15:42

+1

哦,它也看起來像而不是「+」和「/」你使用「 - 」和「_」(不奇怪,我猜,對於URL :-) – Pointy 2011-06-04 17:17:02

2

注意有關不同的瀏覽器:

    • datalength % 4 === 1 - 一個平等是必要的
    • datalength % 4 === 2 - 基於平等是必要的
  • Firefox-等號是可選的,但遵循與Chrome中相同的約定

這是我用來測試它的行(I替換AAAAAA ==每次用不同的字符串):

var url = "data:application/octet-stream;base64,AAAAAA=="; window.open(url);

此外,Firefox和鉻兩者使用+ & /,不-_

來源:

我在Ubuntu 11.04測試使用Chrome 11和Firefox 4

編輯:

我需要這個代碼是tar utility for Javascript。我的代碼按原樣工作,但我希望儘可能符合標準,並且我錯過了我認爲的一個字節。沒有biggie,因爲Linux中的tar可以識別它。

+0

是的,我認爲你是對的。這是其中的一個問題,我發現我認爲我知道的東西,好吧,我真的不知道。或者沒有:-)感謝您提問! – Pointy 2011-06-04 17:55:35

+0

@積分沒關係。你的迴應讓我更加深入瞭解這個問題。這很奇怪,因爲維基百科的文檔與我的測試不匹配...... – tjameson 2011-06-04 18:01:03