2014-09-12 19 views
1

我的頁面狀態可以通過可以序列化爲JSON的JavaScript對象來描述。但我不認爲JSON字符串適合用於片段ID,例如,由於空格和雙引號。將JavaScript對象序列化爲可用作片段標識符(url#hash)的東西的最佳方式是什麼?

將JSON字符串編碼爲base64字符串是明智的,還是有更好的方法?我的目標是允許用戶爲頁面添加書籤,然後在返回到該書籤時,讓一段JavaScript讀取window.location.hash並相應地更改狀態。

回答

0

我認爲你是一個很好的方式。讓我們寫下要求:

  1. 編碼的字符串必須可用作散列,即只有字母和數字。
  2. 原始值必須可以恢復,即散列(md5,sha1)不是一個選項。
  3. 它應該不會太長,以保持可用。
  4. JavaScript應該有一個實現,所以它可以在瀏覽器中生成。

Base64將是一個很好的解決方案。唯一的問題:base64還包含-+等字符,因此與簡單附加JSON字符串(也必須進行URL編碼)相比,您贏不了任何東西。

但幸運的是,這是一個base64的變體,稱爲base64url這正是你所需要的。它專爲您所描述的問題類型而設計。

但是,我無法找到一個JS實現;也許你必須自己寫一個 - 或者做一些更多的研究,比我的15秒掃描前5個谷歌搜索結果還要多。

編輯:第二個想法,我認爲你不需要編寫自己的實現。使用正常的實現,並簡單地將「禁止」字符替換爲適合您的URL的內容。

0

Base64是以文本形式存儲二進制數據的絕佳方法。它僅比原始數據多使用33%的字符/字節,並且主要使用0-9a-zA-Z。它還有三個其他字符需要編碼存儲在URL中,分別爲/,=+。如果您只是使用網址編碼,則會佔用300%(3倍)的大小。

如果您只將字符存儲在URL的片段中,base64編碼的文本不需要重新編碼並且不會更改。但是,如果您想要將數據作爲要訪問的實際URL的一部分發送,那麼它很重要。

由lxg引用,那裏有一個base64url變體。這是base64的一個修改版本,用於替換不安全的字符以存儲在URL中。下面是如何對其進行編碼:

function tobase64url(s) { 
    return btoa(x).replace(/\+/g,'-').replace(/\//g,'_').replace(/=/g,''); 
} 
console.log(tobase64url('\x00\xff\xff\xf1\xf1\xf1\xff\xff\xfe')); 
// Returns "AP__8fHx___-" instead of "AP//8fHx///+" 

而且到Base64字符串從URL解碼:

function frombase64url(s) { 
    return atob(x.replace(/-/g,'+').replace(/_/g, '/')); 
} 
+0

請問爲什麼你帶了'='填充,而不是取代它呢?你知道'atob'函數能夠正確解碼字符串,即使沒有填充字符? – jl6 2014-09-14 20:50:22

+0

@ jl6 base64中的填充僅表示沒有字符,因爲每3個字符都編碼爲base64的4個字符。在Firefox中,'btoa'函數可以在沒有它的情況下對其進行解碼,但我沒有檢查其他瀏覽器。但是URL中只有一行,所以填充只會在最後出現,任何瀏覽器都應該能夠弄清楚。如果你想確保它在解碼之前被添加回來,那麼你最好在'4 * Math.ceil(s.length/4)-s.length' =填充字符上添加。無論如何,把它放開的原因是因爲等號被用在URL中的查詢字符串中。 – Pluto 2014-09-15 20:22:15

相關問題