天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

前端工程師的編碼遭遇戰(zhàn)

  我想,可能是在做第一個(gè)淘寶網(wǎng)的頁面時(shí),工程師只顧寫代碼,而忘了看一看編輯器的默認(rèn)編碼設(shè)置,再后來就將錯(cuò)就錯(cuò)直到今天,如果稍微留神,可能就不會犯下這么一個(gè)低級錯(cuò)誤。沒錯(cuò),“編碼約定”在全站規(guī)范中占有及其重要的權(quán)重,不幸的是,而這個(gè)異常重要的問題卻非常容易被忽略,畢竟它不僅僅是“統(tǒng)一頁面編碼約定”這么簡單,甚至包含全站的安全策略(這是顯而易見的)。而作為F2E面對各式亂碼問題時(shí),更要了解問題的本源,搞清楚能根治問題的方法,而不是依賴于瀏覽器的某種適應(yīng)性暫時(shí)規(guī)避掉亂碼,治標(biāo)不治本。

  從二進(jìn)制碼流到顯示出字符

  眾所周知,字符的編碼方式有兩種慣例,一種是很古老的對ASCII碼做某種語言子集的擴(kuò)展,比如big5gb2312,分別是繁體字?jǐn)U展和簡體字?jǐn)U展,兩者互不兼容,與之類似的編碼還有ISO系列,各個(gè)拉丁文的子編碼集合也不相互兼容,這種編碼的好處是編碼集合很小,壞處是不能同時(shí)使用多種語言,于是就有了另一種編碼慣例:“萬國碼”,全球所有語言做成一個(gè)碼表,即unicode碼表,顯然,這種編碼的壞處是碼表太龐大,好處是同時(shí)使用多種語言。所謂的utf-7、utf-8之類就是unicode的某種相對高效的實(shí)現(xiàn),不管某個(gè)字符用utf編碼為幾個(gè)字節(jié),他們都屬于同一個(gè)unicode超集。我們常遇到的中文編碼是gb2312、gbk、gb18030和utf-8,不嚴(yán)謹(jǐn)?shù)闹v,前三者大致相互兼容,但都和utf-8不兼容。如果一段文本以gbk(碼表)進(jìn)行編碼的話,閱讀軟件只有按照gbk(碼表)解碼才能閱讀。但機(jī)器碼顯示為最終的字符點(diǎn)陣,閱讀軟件(瀏覽器、文本編輯器等)還需要將解碼后(通過查找碼表將連續(xù)的二進(jìn)制碼轉(zhuǎn)換為了字符)的字符碼對應(yīng)到相應(yīng)的點(diǎn)陣,顯然,如果用以顯示文本的字體不包含某個(gè)字符的點(diǎn)陣,這個(gè)字符自然也無法顯示出來。更多背景知識可以參照這個(gè)ppt

  由于瀏覽器比較好的兼容性,一般不會出現(xiàn)因?yàn)樽煮w問題而出現(xiàn)亂碼的情況,但在工程師寫代碼的時(shí)候偶有遇到,比如使用vim以gb2312編碼編輯一個(gè)文件,當(dāng)文件中出現(xiàn)“镕”字時(shí),是無法保存這個(gè)文件的。這是因?yàn)間b2312碼表中不存在這個(gè)字,但指定gb2312編碼的網(wǎng)頁是可以顯示這個(gè)字的,這是因?yàn)闉g覽器通常會采用windows系統(tǒng)編碼來解析gb系的頁面,通常是gbk。

  如果使用editplus或記事本,只需存為ANSI編碼就可以,這些編輯器會根據(jù)碼流去識別到底是gbk還是gb2312還是gb18030的編碼,所以 windows 下很多文本編輯器都沒有強(qiáng)行采用某種特定的編碼,統(tǒng)一使用系統(tǒng)編碼,通常情況下中文win系統(tǒng)中,可以認(rèn)為ANSI就是gbk。如果使用linux系統(tǒng),可以參照這里來正確處理你的編輯器的編碼。

  瀏覽器如何發(fā)送一個(gè)帶有中文的URL

  那么,瀏覽器打開一個(gè)網(wǎng)頁,從敲入網(wǎng)址到最終呈現(xiàn)出UI整個(gè)過程中,是如何處理編碼的呢?整個(gè)過程分兩個(gè)階段,1,發(fā)送URL請求,2,接收數(shù)據(jù)并呈現(xiàn)。HTTP標(biāo)準(zhǔn)對URL編碼有著如是規(guī)定(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.”
“只有字母和數(shù)字[0-9a-zA-Z]、一些特殊符號“$-_.+!*’(),”[不包括雙引號]、以及某些保留字,才可以不經(jīng)過編碼直接用于URL。”

  這里不得不提到URL編碼,盡管根據(jù)RFC的規(guī)定,含有中文的URL是非法的URL,但沒有規(guī)定如何轉(zhuǎn)碼,阮一峰的這篇文章詳細(xì)的介紹了在Firefox和IE中是如何對帶有中文的URL進(jìn)行編碼發(fā)送HTTP請求的。確切的講,URL是一種編碼“方法”,編碼結(jié)果依賴于所采用的“碼表”,即漢字的內(nèi)碼表示形式。所以,相同漢字有N多種URL編碼結(jié)果,“淘寶”的utf8編碼為“%E6%B7%98%E5%AE%9D”,gbk編碼為“%CC%D4%B1%A6”。

  這里需要注意的是,一個(gè)gb系編碼的html頁面中的form提交,表單中的中文編碼會進(jìn)行URL編碼,但是以gbk格式作轉(zhuǎn)碼,utf8頁面的form提交,以utf8格式作轉(zhuǎn)碼。看這兩個(gè)例子:gbk頁面的表單提交utf-8頁面的表單提交

  這時(shí)就需要和后臺程序做好約定,頁面怎么進(jìn)行編碼,后臺邏輯就需要對應(yīng)的解碼。比如淘寶的Search頁面和百度搜索頁一樣,只接收gbk的URL編碼。網(wǎng)上這方面的資料也比較多,這里不再贅述。

  但如果通過JavaScript的encodeURI(encodeURIComponent亦是同理)做URL編碼又會出現(xiàn)什么情況呢?JS只會以utf-8的形式做URL編碼,同樣參照上面兩個(gè)例子,不管頁面是gbk還是utf-8,JS中的URL編碼始終是一樣的。這在使用JS庫模擬form提交時(shí)需要尤為注意,直接提交表單結(jié)果正常,用JS庫或框架提供的方法模擬拼接查詢串提交表單就出問題,也就是這個(gè)原因。所以,在用JS拼接查詢URL的時(shí)候要小心,需要注意后臺程序需要的編碼是什么格式。

  瀏覽器如何以正確的編碼渲染頁面

  HTTP響應(yīng)的數(shù)據(jù)起碼有三個(gè)地方可以埋藏編碼信息:

  1,http頭中的Content-Type
  2,html頁面中的meta標(biāo)簽中指定charset
  3,頁面正文數(shù)據(jù)(瀏覽器可以解析正文二進(jìn)制碼來判斷編碼)

  瀏覽器可以從這三個(gè)地方獲得HTTP響應(yīng)報(bào)文的編碼,此外還有兩個(gè)因素,瀏覽器默認(rèn)編碼和操作系統(tǒng)語言類型。

  淘寶首頁是gbk的編碼,HTTP響應(yīng)頭中指定了文檔編碼為GB2312,同時(shí)meta中的charset和頁面正文都是gbk編碼,瀏覽器渲染正確。

  content-type中的編碼設(shè)置

  源碼中的meta標(biāo)簽

  如果三者編碼不一致,瀏覽器會首先讀取http頭中的content-type,若沒有設(shè)定編碼,再查找頁面中meta標(biāo)簽中的charset設(shè)定,如果還沒有就以瀏覽器默認(rèn)編碼來顯示,如果默認(rèn)編碼沒有指定,瀏覽器會通過解析正文內(nèi)容來判斷編碼。所以,頁面是gbk編碼,即便meta屬性中設(shè)置charset=utf-8,只要content-type中設(shè)定為gbk(或者GB2312、GB18030),該頁面就正常顯示,如果這時(shí)沒有設(shè)定content-type的編碼,瀏覽器就會以meta中的charset屬性為準(zhǔn),頁面出現(xiàn)亂碼。

  在php中可以這樣設(shè)置content-type的編碼:header('Content-Type: text/html; charset=GBK');

  正確的載入JS文件

  html頁面載入js文件的時(shí)候,需要指定js文件的編碼才能正確引用,比如:<script src="gbk.js" charset="gbk" ></script>

  可以參照這個(gè)demo

  JSONP里的中文處理

  根據(jù)上面的例子,我們知道載入外部JS文件只要指定charset就可以,對JSONP來講也是如此,但有一個(gè)更徹底的杜絕亂碼的方法,將JS文件進(jìn)行unicode編碼,這是因?yàn)镴S引擎的內(nèi)碼是unicode,所以只要是unicode的文本JS都可以識別。就像這樣:

  php中的json_encode函數(shù)可以直接將數(shù)組作unicode轉(zhuǎn)碼。通過JS也可以進(jìn)行unicode編碼,參照這個(gè)Demo

  通過JS獲取URL

  我們注意到,在使用Firefox打開的地址中包含中文時(shí),將其拷貝粘貼到另外的地方卻沒有得到中文,而是編碼后的URL。這是因?yàn)闉g覽器自作聰明的將URL解碼為中文來顯示的,當(dāng)我們需要抓取URL的時(shí)候需要特別小心,這個(gè)Demo在Firefox和IE下打開,JS得到的URL是不一致的。

  Firefox:

  IE:

  如果這個(gè)頁面不和后臺數(shù)據(jù)發(fā)生交互,直接通過document.location.href來取URL是ok的,一旦和后臺發(fā)生交互,則需要非常小心,最常見出問題的場景是帶入登錄頁的回調(diào)地址。比如通過這個(gè)地址進(jìn)入淘寶首頁:http://www.taobao.com/?淘寶

  在Firefox和IE下都是可以正常訪問的,這時(shí)點(diǎn)擊吊頂中的“登錄”,進(jìn)入登錄頁,可以看到在Firefox下的回調(diào)地址為:

  而在IE下的回調(diào)地址為:

  這時(shí)登錄淘寶,頁面跳轉(zhuǎn)為淘寶首頁,可以看到Firefox的地址欄中的URL是正確的,而在IE的地址欄中出現(xiàn)了亂碼

  Firefox下

  IE下

  解決辦法就是不要用JS去抓取URL寫入回調(diào),通過登錄頁面的Ref或其他方式來抓取。

  gbk的頁面如何通過JS得到gbk格式的URL編碼

  我們知道,gbk的頁面提交表單是可以作基于gbk的URL編碼的,基于這一點(diǎn),我們可以封裝一個(gè)函數(shù),實(shí)現(xiàn)在gbk頁面中使用JS得到gbk格式的URL編碼。參照這個(gè)Demo,Demo中模擬提交一個(gè)表單,然后抓取表單提交的結(jié)果,進(jìn)而得到gbk格式的URL編碼。

  這樣,通過JS就可以控制我希望得到的URL編碼了。但在utf-8的頁面中是無法實(shí)現(xiàn)的。這一點(diǎn)需要尤為注意。

it知識庫前端工程師的編碼遭遇戰(zhàn),轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 国产精品系列在线观看 | 国产精品日本不卡一区二区 | 色多多污网站在线观看 | 日韩 亚洲 欧美 中文 高清 | 久久久久久免费观看 | 精品久久久麻豆国产精品 | 国自产拍 高清精品 | 99久久精品国产交换 | 亚洲区 bt下载 | 99麻豆精品国产人妻无码 | 俄罗斯12x13x处 | 日本经典片免费看 | YY600800新视觉理论私人 | 国产精品免费大片一区二区 | 亚洲卫视论坛 | 成 人 免费 黄 色 网站无毒下载 | 亚洲免费在线视频观看 | 亚洲AV无码乱码国产麻豆P | 老头xxx | 亚洲日本va中文字幕久久 | 友田真希息与子中文字幕 | 国内精品视频一区二区在线观看 | 亚洲精品久久99蜜芽尤物TV | 一边亲着一面膜下奶韩剧免费 | 一起洗澡的老师免费播放 | 边摸边吃奶边做激情叫床视 | 秋霞电影院兔费理论观频84mb | 中国国产不卡视频在线观看 | 美女脱精光让男生桶下面 | 无人区日本电影在线观看 | 在线观看日本污污ww网站 | 99热精品一区 | 人妻 中文无码 中出 | 亚洲欧美人成视频在线 | 大陆极品少妇内射AAAAAA | 极品网红液液酱粉嫩福利照子凌酱 | 这里只有精品网 | 国产午夜精品一区二区理论影院 | 欧美 国产 日产 韩国 在线 | 国产亚洲视频中文字幕 | 国产麻豆剧果冻传媒免费网站 |