不要小看它——編碼與解碼

前言

說說我爲何要寫關於編碼的一篇博文?有兩個緣由

1.藝龍的面試面試官問到了,讓我知道了你想擴展的你的基礎,你不能放棄任意一個知識點前端

2.就是今天作業務碰到了這個bug,確定有人想知道,這個會產生什麼bug,bug通常都是不注意細節,纔會致使的,業務中有一個分享到朋友圈和微信好友的一個業務模塊,你們都知道,通常這種模塊都是要利用客戶端給你提供一個hybrid的一個接口,而後,你經過調用這個接口,來完成分享這一個舉動,可是在測試的時候並無發現問題,可是到了線上問題來了,咱們一個主管的帳號分享不了,可是不少人的帳號卻能夠分享,這種問題是最煩人的,並且更氣人的是安卓機均可以分享,那咱們是否是該分分鍋,ios的鍋?仍是帳號的鍋?又或者是前端的鍋?故事發展到最後,不少人都忙了一下午來查找bug,我來寫這篇文章,確定說明是前端的鍋啊,有人奇怪,這安卓的,ios的部分都是能夠的,說明功能沒問題,我當時也是這麼想的,可是結果卻出乎意料,先說說爲何部分ios能夠,由於url裏面帶了暱稱參數,一部分人的暱稱是英文,一部分是中文,這就是結果——在url中的中文字符都要用base64轉成ASCII字符進行傳遞。ios

瞭解篇——怎麼用

不少不了解的人,應該更關心怎麼用,這裏我會講幾個web的api,後面一部分博文,可能會深刻點,無聊點,程序員寫做能力欠缺0.0git

encodeURIComponent和encodeURI

這兩個接口是咱們常常用的,他們的用途一致,是對URL進行編碼,可是他們之間仍是有區別程序員

  • encodeURI不能對下列字符進行編碼,ASCII字母、數字、~!@#$&*()=:/,;?+'
  • encodeURIComponent不能對下列字符進行編碼,ASCII字母、數字、~!*()'

總結,encodeURIComponent的編碼範圍比encodeURI大,個人問題就是用encodeURIComponent解決的github

escape

上面的兩個對URL進行編碼,這個接口就是對字符串進行編碼,讓字符串能夠在全部計算機上被讀取,編碼以後的效果是%XX或者%uXXXX這種形式。web

  • 注意,它針對的是字符串,不適用於URL,不會對 ASCII字母、數字、@*/+
//舉個例子
let str = '來鏵敏';
let encodeStr = escape(str);
console.log(encodeStr);//%u6765%u94E7%u654F複製代碼

前三個的用法

  • 不針對URL的那麼就用escape
  • 針對整個http的,用encodeURI
  • 針對http的參數的,就用encodeURIComponent

unescape、decodeURI和decodeURIComponent

這三者是解碼用的,分別對應上面的三個,看下面的例子就知道了面試

let str = '來鏵敏';
let encodeStr = escape(str);
console.log(encodeStr);
console.log(unescape(encodeStr));
let _encodeStr = encodeURIComponent(str);
console.log(_encodeStr);
console.log(decodeURIComponent(_encodeStr));複製代碼

輸出結果我就不寫了,有幾點須要注意,編碼和解碼需一一對應,默寫場景encodeURI進行編碼的decodeURIComponent能夠解碼,可是escape編碼的decodeURIComponent解碼會報錯算法

瞭解篇——有什麼用

URL編碼傳遞

URL中容許的只有英文字符,阿拉伯數字,某些標誌,你確定沒有看過這樣的網站:api

http://github.com/laihuamin/來點贊複製代碼

爲何會上述網站不行呢,由於網絡標準RFC 1738作了硬性規定:瀏覽器

原文:"...Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL."

  • 因此綜上所述,編碼是爲了一些不被規定的字符在URL中傳遞變得合法

瀏覽器信息加密

用編碼能夠對前端的一些重要信息進行加密,其實前端並無上面嚴格意義上的加密,這裏說的加密更多偏向與混淆,咱們來實現一個簡單點的加密:

//這裏實現的是對js代碼的加密,這是個例子
console.log('我要加密這個語句');
//下面是加密和解密處理
escape('console.log("我要加密這個語句")')
//先進行編碼得到加密後的
const code = unescape(console.log%28%22%u6211%u8981%u52A0%u5BC6%u8FD9%u4E2A%u8BED%u53E5%22%29)
eval(code)複製代碼
  • 總結,第二點功能,沒有第一點功能來的實用,其實能夠不用記憶,若是還有其餘上面功能的歡迎補充

基礎篇——有哪些

說了這麼多編碼,那到底有多少種編碼形式呢?熟悉計算機的朋友應該都聽過這樣的詞彙:ASCII、Unicode、UTF-八、UTF-16等等,那咱們就來絮叨絮叨常見的

ASCII

ASCII碼咱們在熟悉不過,它是使用8位二進制來表示英文字符和符號,可是吹生出一個問題,中華文化博大精深,光漢字就有幾萬個,256個字符哪裏夠用呢。。。。

非ASCII編碼

一個英文字母一個字節足夠表示,可是10萬個漢字,一個字節怎麼夠,那就兩個唄,256x256才足以表示,中文編碼就是GB2312,但在日本或者其餘地方就不能使用,因此衆多的編碼方式,沒有統一性

Unicode

衆多的編碼方式困擾這你們,電子郵件也時常出現亂碼,若是有一種字符集能夠把全部的字符都收錄進來,不就能夠解決問題,Unicode應運而生,Unicode固然是一個很大的集合,如今的規模能夠容納100多萬個符號。

Unicode的問題

  • Unicode只是一個字符集,並無規定二進制碼該怎麼儲存,這樣就會引起一個問題,一個漢字兩個字節,一個英文字符一個字節,計算機把一個漢子當成兩個英文字符來讀寫怎麼辦
  • 前者還會致使一種結果,爲了解決前面的問題,咱們勢必多添加幾個000去表示究竟是幾個字節的字符,這樣存儲空間有了巨大的浪費

UTF-8

UTF-8是Unicode的一種實現,它是一種可變的編碼規則,當在ASCII範圍內時,用一個字節讀取,若是在範圍以外,就用多個字節讀取,注意,中文字符在Unicode中是兩個字節,在UTF-8中是3個字節,Unicode到UTF-8的轉換規則有相應的算法

總結篇

聊了這麼多關於編碼的,我簡單總結幾點:

  • 現有ASCII編碼,可是對於中文和多國語言,不夠用了,中國人民對ASCII進行擴展,產生了GB2312編碼,可是仍是不夠用,以後出現了GBK編碼
  • 不少國家編碼規則不統一,吹生出了Unicode編碼方式,可是因爲Unicode的缺陷,因此UTF-8應運而生,因此咱們常常會在網頁的head標籤中看到
    <meta charset="utf-8">複製代碼
  • UTF這麼方便,爲何國內還有人使用GBK編碼呢,就是由於UTF的佔用體積過大,若是僅僅面向國人的,仍是建議GBK編碼

知識來源網絡,實踐得到真知,借鑑網絡的地方過多,沒法著名出處,侵刪

備註:
若是喜歡我博客的能夠給我點個贊,在個人github還有我精心準備的博文,喜歡的能夠去點個star,謝謝支持🙏

相關文章
相關標籤/搜索