摘要:當然,也可自己寫一個轉(zhuǎn)換函數(shù),按照一定規(guī)則便行為編碼的字節(jié),如下例中國結(jié)果中國結(jié)果結(jié)果通過簡單的函數(shù),就可以完成編碼到編碼的轉(zhuǎn)換,進而完成寬字節(jié)字符到編碼的轉(zhuǎn)換。
前端開發(fā)過程中會接觸各種各樣的編碼,比較常見的主要是 UTF-8 和 HTML 實體編碼,但是 web 前端的世界卻不止這兩種編碼,而且編碼的選擇也會造成一定的問題,如前后端開發(fā)過程中不同編碼的兼容、多字節(jié)編碼可能會造成的 XSS 漏洞等。因此,本文旨在更好的全面了解涉及前端開發(fā)領(lǐng)域的字符編碼,避免可能出現(xiàn)的交互和開發(fā)中的忽視的漏洞。
URL 編碼我曾經(jīng)在 URL 編碼解碼和 base64 一文中講述了 URL 編碼中的三組函數(shù),并對比了這三組函數(shù)與 base64 編碼的關(guān)系,在此簡要說明一下。
escape/unescape 函數(shù)針對寬字符做 unicode 編碼,并針對碼值做十六進制編碼,所以使用 escape 針對漢字編碼會得到形如 uxxxx 的結(jié)果;encodeURI/decodeURI, encodeURIComponent/decodeURIComponent 函數(shù)針對寬字節(jié)編碼卻不同于 escape,首先針對寬字節(jié)字符進行 UTF-8 編碼,然后針對編碼后的結(jié)果進行 % 替換,得到結(jié)果。以上所述都是針對寬字節(jié)而言,對于編碼靠前的 ASCII 字符而言,上述三組函數(shù)的安全字符的范圍也有所不同,具體可在上文中了解。
base64 編碼base64 編碼在前端通常用于圖片和 icon 的編碼,它將每 3 個 8 位字節(jié)為一組,分成 4 組 6 位字節(jié),并且每個字節(jié)的高位補零,形成 4 個 8 位的字節(jié),由此可看出 base64 編碼是可逆推的。在大多數(shù)瀏覽器中,提供了 ASCII 字符的 base64 編碼函數(shù),即 window.btoa()。該函數(shù)無法針對寬字節(jié)進行base64編碼,若針對中文編碼,則需現(xiàn)轉(zhuǎn)換位 UTF-8 編碼,然后進行 base64 編碼。
function unicodeToBase64(s){ return window.btoa(unescape(encodeURIComponent(s))) }
通過 encodeURIComponent 對寬字節(jié)字符編碼,是 %xx 形式的編碼,與 UTF-8 編碼的區(qū)別僅在于前綴(這是由規(guī)范 RFC3986 決定的,將非 ASC 字符進行某種形式編碼,并轉(zhuǎn)換為 16 進制,并在字節(jié)前加上“%”)。因此通過 unescape(encodeURIComponent(s)) 可以轉(zhuǎn)化為 UTF-8 字節(jié)。當然,也可自己寫一個轉(zhuǎn)換函數(shù),按照一定規(guī)則便行為 UTF-8 編碼的字節(jié),如下例:
unescape(encodeURIComponent("中國")) //結(jié)果:"??-???" encodeURIComponent("中國") //結(jié)果:"%E4%B8%AD%E5%9B%BD" console.log("u00E4u00B8u00ADu00E5u009Bu00BD") // 結(jié)果: "??-???"
通過簡單的 replace 函數(shù),就可以完成 URL 編碼到 UTF-8 編碼的轉(zhuǎn)換,進而完成寬字節(jié)字符到base64編碼的轉(zhuǎn)換。有了這個函數(shù),我們手動生成一些 data URI 形式的內(nèi)容,只需制定 MIME 類型和編碼方式,就可以實現(xiàn)文本的轉(zhuǎn)換,如以下代碼:
abc // 未編碼前:test前端 UTF-8 編碼與后端 GBK 編碼的兼容
目前前端大都采用 UTF-8 進行編碼,不管是 html、js 抑或是 css,而后端則由于歷史原因大都采用 GBK 或 GB2312 進行解碼,因此前端通過 parameter 傳遞的 URL 編碼的字符串就不可能直接在后臺進行解碼,為了更好的兼容性,前端可進行兩次 URL 編碼,即 encodeURIComponent(encodeURIComponent(“中國”)),這樣后端接收到參數(shù)后,先使用 GBK 或 GB2312 解碼,得到了 UTF-8 編碼后再使用 UTF-8 解碼即可。兩次編碼主要是利用“ASC 字符使用 GBK 或 GB2312 編碼不變”的特點完成,富有技巧。
HTML 實體編碼與進制編碼實體編碼針對HTML的預(yù)留字符而言,如 <> 等。實體編碼有兩種形式 &實體名; 或 &entity_number;,由于瀏覽器對 &實體名; 的兼容性有差別,因此最好采用實體號的形式編碼。
進制編碼,顧名思義將ASC字符對應(yīng)的碼值按照十六進制或十進制編碼,并轉(zhuǎn)化為 (16進制) 或D;(10進制) 形式。
單單針對實體編碼而言并沒有什么特殊強調(diào)的點,之所以把它多帶帶列為一個章節(jié),意在強調(diào)這兩種編碼與 js 代碼的作用域的關(guān)系。
1、另外,對于 js 輸出點的過濾其實并不僅限于上文提到的如 eval、setTimeout、Function 等幾個,由于 JS 語法比較靈活相對“漏洞”較多,可使用的“線索”也越豐富,如前段時間在 Stackoverflow 上發(fā)現(xiàn)的一個問題,即
(0)["constructor"]["constructor"]("return "abc;"")()同樣可以執(zhí)行 JS 代碼,確實挺有特點的,具體為什么上述形式可以執(zhí)行代碼,請讀者自己仔細品味。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/79395.html
摘要:當后端將數(shù)據(jù)取出再傳給前端時,發(fā)生了編碼混亂的問題。這樣的編碼錯誤問題導(dǎo)致數(shù)據(jù)上的,會造成不良的用戶體驗。但是,不幸的是,各方對該編碼的規(guī)則是不同的,這也造成亂碼的隱患。 本文由作者朱臻授權(quán)網(wǎng)易云社區(qū)發(fā)布。 1問題案例 曾在開發(fā)過程中,我們遇到了BASE64編碼亂碼的問題,該問題的場景如下: 當web前端,將帶有中文字符的字符串base64編碼后,傳到后端。當后端將數(shù)據(jù)取出再傳給we...
摘要:導(dǎo)語本文源于微信游戲春節(jié)王者搖心愿活動英雄語音祝福自定義輸入模塊開發(fā)過程,對踩過的前端字符編碼的坑進行記錄總結(jié)。只規(guī)定了字符編碼,而并沒有規(guī)定具體的編碼方式。 導(dǎo)語 本文源于微信游戲春節(jié)王者搖心愿活動英雄語音祝福自定義輸入模塊開發(fā)過程,對踩過的前端字符編碼的坑進行記錄總結(jié)。 Unicode 字符 Unicode(中文:萬國碼、國際碼、統(tǒng)一碼、單一碼)是計算機科學(xué)領(lǐng)域里的一項業(yè)界標準。它...
摘要:性能優(yōu)化頁面渲染減少頁面修改元素多個樣式可以通過修改完成這樣可以把多次減少為一次修改元素多個樣式可以分為三步先隱藏再修改最后顯示。 代碼優(yōu)化 這個部分僅僅將代碼優(yōu)化本身,不考慮性能,關(guān)于代碼部分的性能優(yōu)化在 頁面渲染 部分 代碼優(yōu)化 中 HTML+CSS 符合 XHTML 規(guī)范: 小寫,正確嵌套,必須關(guān)閉; 雙引號,合理縮進,utf-8編碼; 標簽語義化,便于維護; 合理注釋,比如 ...
摘要:性能優(yōu)化頁面渲染減少頁面修改元素多個樣式可以通過修改完成這樣可以把多次減少為一次修改元素多個樣式可以分為三步先隱藏再修改最后顯示。 代碼優(yōu)化 這個部分僅僅將代碼優(yōu)化本身,不考慮性能,關(guān)于代碼部分的性能優(yōu)化在 頁面渲染 部分 代碼優(yōu)化 中 HTML+CSS 符合 XHTML 規(guī)范: 小寫,正確嵌套,必須關(guān)閉; 雙引號,合理縮進,utf-8編碼; 標簽語義化,便于維護; 合理注釋,比如 ...
閱讀 3284·2023-04-26 01:39
閱讀 3429·2023-04-25 18:09
閱讀 1690·2021-10-08 10:05
閱讀 3307·2021-09-22 15:45
閱讀 2918·2019-08-30 15:55
閱讀 2466·2019-08-30 15:54
閱讀 3223·2019-08-30 15:53
閱讀 1387·2019-08-29 12:32