深圳微網(wǎng)站建設(shè)今日油價(jià)92汽油
URL編碼和Base64編碼
- 前言
- 一、URL編碼
- 1. URLEncoder和URLDecoder
- 2. URL編碼規(guī)則
- 3. Javascript 原生提供三對(duì) Url編碼 的函數(shù)
- 3.1 三對(duì)函數(shù)的不同點(diǎn)
- 二、Base64編碼
- 1. Base64編碼規(guī)則
- 2. Base64編碼使用
- 3. JavaScript 原生提供兩個(gè) Base64 相關(guān)的方法
- 總結(jié)
前言
數(shù)據(jù)操作過程中,經(jīng)常涉及到編碼與解碼等相關(guān)操作,如web請(qǐng)求時(shí)會(huì)對(duì)url進(jìn)行編碼,其中的中文等字符會(huì)轉(zhuǎn)義為其他內(nèi)容;中文字符串?dāng)?shù)據(jù)傳輸時(shí),會(huì)將其使用base64編碼并在接收后解碼,以避免亂碼的出現(xiàn)。
一、URL編碼
1. URLEncoder和URLDecoder
URLDecoder 和 URLEncoder 用于普通字符串 和 application/x-www-form-urlencoded MIME 字符串之間的相互轉(zhuǎn)換。
當(dāng)URL地址里包含非西歐字符的字符串時(shí),瀏覽器會(huì)將這些非西歐字符串轉(zhuǎn)換成application/x-www-form-urlencoded MIME 字符串。
- URLDecoder類包含一個(gè)decode(String s,String enc)靜態(tài)方法,它可以將application/x-www-form-urlencoded MIME字符串轉(zhuǎn)成普通字符串;
- URLEncoder類包含一個(gè)encode(String s,String enc)靜態(tài)方法,它可以將普通字符串轉(zhuǎn)換成application/x-www-form-urlencoded MIME字符串。
2. URL編碼規(guī)則
對(duì) String 編碼時(shí),使用以下規(guī)則:
- 字母、數(shù)字和字符, “a” 到 “z”、”A” 到 “Z” 和 “0” 到 “9” 保持不變;
- 特殊字符 “.”、”-“、”*” 和 “_” 保持不變;
- 空格字符 ” ” 轉(zhuǎn)換為一個(gè)加號(hào) “+”;
- url編碼時(shí)會(huì)將 + 編碼成空格;
- 除此之外,所有的其他字符都是不安全的,會(huì)變成以 % 開頭的字符;
- 對(duì)于一個(gè)中文,會(huì)使用3個(gè)字節(jié)表示 由于以上限制內(nèi)容,因此URL編碼是一種限制性編碼方式。
3. Javascript 原生提供三對(duì) Url編碼 的函數(shù)
Javascript中提供了3對(duì)函數(shù)用來將不安全不合法的Url字符轉(zhuǎn)換為合法的Url字符表示 ,它們分別是:
- escape / unescape
- encodeURI / decodeURI
- encodeURIComponent / decodeURIComponent
由于解碼和編碼的過程是可逆的,因此這里只解釋編碼的過程。
3.1 三對(duì)函數(shù)的不同點(diǎn)
(1) 安全字符不同
下面列出了這三個(gè)函數(shù)的安全字符(即函數(shù)不會(huì)對(duì)這些字符進(jìn)行編碼):
- escape(69個(gè)):*/@±._0-9a-zA-Z
- encodeURI(82個(gè)):!#$&'()*+,/:;=?@-._~0-9a-zA-Z
- encodeURIComponent(71個(gè)):!'()*-._~0-9a-zA-Z
(2) 兼容性不同
escape函數(shù)是從Javascript 1.0的時(shí)候就存在了,其他兩個(gè)函數(shù)是在Javascript 1.5才引入的。但是由于Javascript 1.5已經(jīng)非常普及了,所以實(shí)際上使用encodeURI和encodeURIComponent并不會(huì)有什么兼容性問題。
(3) 對(duì)Unicode字符的編碼方式不同
escape 和 encodeURI / encodeURIComponent 不是同一類。
簡單來說,escape 是對(duì)字符串進(jìn)行編碼, 而另外兩種是對(duì)URL進(jìn)行編碼,作用是讓它們?cè)谒须娔X上可讀。編碼之后的效果是%XX或者%uXXXX這種形式。其中 ASCII字母,數(shù)字 ,@*/+ 這幾個(gè)字符不會(huì)被編碼,其余的都會(huì)。
注意:當(dāng)需要對(duì)URL編碼時(shí),請(qǐng)忘記這個(gè)方法,這個(gè)方法是針對(duì)字符串使用的,不適用于URL。
(4) 適用場(chǎng)合不同
encodeURI 被用作對(duì)一個(gè)完整的URI進(jìn)行編碼,而 encodeURIComponent 被用作對(duì)URI的一個(gè)組件進(jìn)行編碼。
對(duì)URL編碼是常見的事,所以這兩個(gè)方法應(yīng)該是實(shí)際中要特別注意的。它們都是編碼URL,唯一區(qū)別就是 編碼的字符范圍:
- encodeURI 方法不會(huì)對(duì)下列字符編碼:ASCII字母 ,數(shù)字 , ~!@#$&*()=:/,;?+’
- encodeURIComponent 方法不會(huì)對(duì)下列字符編碼 :ASCII字母 ,數(shù)字 , ~!*()’
所以 encodeURIComponent 比 encodeURI 編碼的范圍更大。
實(shí)際例子來說,encodeURIComponent 會(huì)把 http:// 編碼成 http%3A%2F%2F ,而encodeURI 卻不會(huì)。
總的來說,最重要的是什么場(chǎng)合應(yīng)該用什么方法:
- 如果只是編碼 字符串,和URL沒有關(guān)系,那么使用 escape;
- 如果需要編碼 整個(gè)URL,并需要使用這個(gè)URL,那么用 encodeURI;
例如:
encodeURI("http://www.cnblogs.com/hl/some other thing");
編碼后會(huì)變?yōu)?#xff1a;
"http://www.cnblogs.com/hl/some%20other%20thing";
其中,空格被編碼成了%20。但是如果你用了encodeURIComponent,那么結(jié)果變?yōu)?“http%3A%2F%2Fwww.cnblogs.com%2Fseason-huang%2Fsome%20other%20thing”
看到區(qū)別了嘛?連 “/” 都被編碼了,整個(gè)URL已經(jīng)沒法用了。
- 如果需要編碼 URL中的參數(shù),使用 encodeURIComponent 是最好方法。
// param為參數(shù)
let param = "http://www.cnblogs.com/season-huang/"; param = encodeURIComponent(param);let url = "http://www.cnblogs.com?next=" + param;
console.log(url);
// "http://www.cnblogs.com?next=http%3A%2F%2Fwww.cnblogs.com%2Fseason-huang%2F
看到了吧,參數(shù)中的 “/” 可以編碼,如果用 encodeURI 肯定要出問題,因?yàn)楹竺娴?/ 是需要編碼的。
二、Base64編碼
1. Base64編碼規(guī)則
Base64是一種將二進(jìn)制數(shù)據(jù)用文本表示的編碼算法,它只包含64個(gè)字符,A - Z,a - z,0 - 9,+ ,/ , 對(duì)應(yīng)索引為 0 - 63。
- base64編碼時(shí)選取3個(gè)字節(jié)為一組,進(jìn)行重新編排,將原來8個(gè)bit為一個(gè)字節(jié)改為每6個(gè)bit作為新的字節(jié),3個(gè)字節(jié)編碼形成4個(gè)字節(jié);
- 如果字符字節(jié)長度不是3的倍數(shù),會(huì)使用\x00字節(jié)補(bǔ)足,再根據(jù)補(bǔ)足的數(shù)量添加等量的=標(biāo)識(shí);
- 如43yW56CB5rWL6K+HUQ==代表,編碼時(shí)補(bǔ)足兩個(gè)\x00,編碼后增加兩個(gè)+;
2. Base64編碼使用
如果需要將包含中文的utf-8編碼字符轉(zhuǎn)換稱ASCII碼,則需要使用Base64作為中間編碼來保證字符數(shù)據(jù)的穩(wěn)定。
- 編碼,要將utl-8字符使用base64編碼,得到結(jié)果后將字符轉(zhuǎn)成ASCII編碼;
- 解碼,將ASCII編碼解析為Base64字符串,使用Base64解碼方法解析為utf-8的結(jié)果數(shù)據(jù);
- 除了針對(duì)字符串外,Base64還可以對(duì)不太大的文件進(jìn)行編碼,使用字符序列表示二進(jìn)制文件;
3. JavaScript 原生提供兩個(gè) Base64 相關(guān)的方法
- btoa():任意值轉(zhuǎn)為 Base64 編碼;
- atob():Base64 編碼轉(zhuǎn)為原來的值;
注意,這兩個(gè)方法不適合非 ASCII 碼的字符,會(huì)報(bào)錯(cuò)。
要將非 ASCII 碼字符轉(zhuǎn)為 Base64 編碼,必須中間插入一個(gè)轉(zhuǎn)碼環(huán)節(jié),再使用這兩個(gè)方法。
function b64Encode(str) {return btoa(encodeURIComponent(str));
}function b64Decode(str) {return decodeURIComponent(atob(str));
}b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"
總結(jié)
參考鏈接:
URL編碼和Base64編碼
Web開發(fā)須知:URL編碼與解碼
escape,encodeURI,encodeURIComponent有什么區(qū)別?