我的頁面狀態可以通過可以序列化爲JSON的JavaScript對象來描述。但我不認爲JSON字符串適合用於片段ID,例如,由於空格和雙引號。將JavaScript對象序列化爲可用作片段標識符(url#hash)的東西的最佳方式是什麼?
將JSON字符串編碼爲base64字符串是明智的,還是有更好的方法?我的目標是允許用戶爲頁面添加書籤,然後在返回到該書籤時,讓一段JavaScript讀取window.location.hash
並相應地更改狀態。
我的頁面狀態可以通過可以序列化爲JSON的JavaScript對象來描述。但我不認爲JSON字符串適合用於片段ID,例如,由於空格和雙引號。將JavaScript對象序列化爲可用作片段標識符(url#hash)的東西的最佳方式是什麼?
將JSON字符串編碼爲base64字符串是明智的,還是有更好的方法?我的目標是允許用戶爲頁面添加書籤,然後在返回到該書籤時,讓一段JavaScript讀取window.location.hash
並相應地更改狀態。
我認爲你是一個很好的方式。讓我們寫下要求:
Base64將是一個很好的解決方案。唯一的問題:base64還包含-
和+
等字符,因此與簡單附加JSON字符串(也必須進行URL編碼)相比,您贏不了任何東西。
但幸運的是,這是一個base64的變體,稱爲base64url
這正是你所需要的。它專爲您所描述的問題類型而設計。
但是,我無法找到一個JS實現;也許你必須自己寫一個 - 或者做一些更多的研究,比我的15秒掃描前5個谷歌搜索結果還要多。
編輯:第二個想法,我認爲你不需要編寫自己的實現。使用正常的實現,並簡單地將「禁止」字符替換爲適合您的URL的內容。
Base64是以文本形式存儲二進制數據的絕佳方法。它僅比原始數據多使用33%的字符/字節,並且主要使用0-9
,a-z
和A-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, '/'));
}
請問爲什麼你帶了'='填充,而不是取代它呢?你知道'atob'函數能夠正確解碼字符串,即使沒有填充字符? – jl6 2014-09-14 20:50:22
@ jl6 base64中的填充僅表示沒有字符,因爲每3個字符都編碼爲base64的4個字符。在Firefox中,'btoa'函數可以在沒有它的情況下對其進行解碼,但我沒有檢查其他瀏覽器。但是URL中只有一行,所以填充只會在最後出現,任何瀏覽器都應該能夠弄清楚。如果你想確保它在解碼之前被添加回來,那麼你最好在'4 * Math.ceil(s.length/4)-s.length' =填充字符上添加。無論如何,把它放開的原因是因爲等號被用在URL中的查詢字符串中。 – Pluto 2014-09-15 20:22:15