關(guān)于URL編碼

關(guān)于URL編碼

一忱叭、問(wèn)題的由來(lái)

URL就是網(wǎng)址拧簸,只要上網(wǎng)栗恩,就一定會(huì)用到。

圖片.png

一般來(lái)說(shuō)噪猾,URL只能使用英文字母、阿拉伯?dāng)?shù)字和某些標(biāo)點(diǎn)符號(hào)筑累,不能使用其他文字和符號(hào)袱蜡。比如,世界上有英文字母的網(wǎng)址"http://www.abc.com"慢宗,但是沒(méi)有希臘字母的網(wǎng)址"http://www.aβγ.com"(讀作阿爾法-貝塔-伽瑪.com)坪蚁。這是因?yàn)榫W(wǎng)絡(luò)標(biāo)準(zhǔn)RFC 1738做了硬性規(guī)定:

    "...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]、一些特殊符號(hào)"$-_.+!*'(),"[不包括雙引號(hào)]婆廊、以及某些保留字迅细,才可以不經(jīng)過(guò)編碼直接用于URL。"

這意味著淘邻,如果URL中有漢字,就必須編碼后使用湘换。但是麻煩的是宾舅,RFC 1738沒(méi)有規(guī)定具體的編碼方法,而是交給應(yīng)用程序(瀏覽器)自己決定彩倚。這導(dǎo)致"URL編碼"成為了一個(gè)混亂的領(lǐng)域筹我。

下面就讓我們看看,"URL編碼"到底有多混亂帆离。我會(huì)依次分析四種不同的情況蔬蕊,在每一種情況中,瀏覽器的URL編碼方法都不一樣哥谷。把它們的差異解釋清楚之后岸夯,我再說(shuō)如何用Javascript找到一個(gè)統(tǒng)一的編碼方法。

二们妥、情況1:網(wǎng)址路徑中包含漢字

打開IE(我用的是8.0版)猜扮,輸入網(wǎng)址"http://zh.wikipedia.org/wiki/春節(jié)"。注意监婶,"春節(jié)"這兩個(gè)字此時(shí)是網(wǎng)址路徑的一部分旅赢。

圖片.png

查看HTTP請(qǐng)求的頭信息,會(huì)發(fā)現(xiàn)IE實(shí)際查詢的網(wǎng)址是"http://zh.wikipedia.org/wiki/%E6%98%A5%E8%8A%82"惑惶。也就是說(shuō)煮盼,IE自動(dòng)將"春節(jié)"編碼成了"%E6%98%A5%E8%8A%82"。

圖片.png

我們知道带污,"春"和"節(jié)"的utf-8編碼分別是"E6 98 A5"和"E8 8A 82"僵控,因此,"%E6%98%A5%E8%8A%82"就是按照順序刮刑,在每個(gè)字節(jié)前加上%而得到的喉祭。(具體的轉(zhuǎn)碼方法养渴,請(qǐng)參考我寫的《字符編碼筆記》。)

在Firefox中測(cè)試泛烙,也得到了同樣的結(jié)果理卑。所以,結(jié)論1就是蔽氨,網(wǎng)址路徑的編碼藐唠,用的是utf-8編碼。

三鹉究、情況2:查詢字符串包含漢字

在IE中輸入網(wǎng)址"http://www.baidu.com/s?wd=春節(jié)"宇立。注意自赔,"春節(jié)"這兩個(gè)字此時(shí)屬于查詢字符串妈嘹,不屬于網(wǎng)址路徑,不要與情況1混淆润脸。

圖片.png

查看HTTP請(qǐng)求的頭信息他去,會(huì)發(fā)現(xiàn)IE將"春節(jié)"轉(zhuǎn)化成了一個(gè)亂碼。

圖片.png

切換到十六進(jìn)制方式铭段,才能清楚地看到,"春節(jié)"被轉(zhuǎn)成了"B4 BA BD DA"。

圖片.png

我們知道鲜结,"春"和"節(jié)"的GB2312編碼(我的操作系統(tǒng)"Windows XP"中文版的默認(rèn)編碼)分別是"B4 BA"和"BD DA"展运。因此,IE實(shí)際上就是將查詢字符串精刷,以GB2312編碼的格式發(fā)送出去拗胜。

Firefox的處理方法,略有不同怒允。它發(fā)送的HTTP Head是"wd=%B4%BA%BD%DA"埂软。也就是說(shuō),同樣采用GB2312編碼,但是在每個(gè)字節(jié)前加上了%勘畔。

圖片.png

所以所灸,結(jié)論2就是,查詢字符串的編碼炫七,用的是操作系統(tǒng)的默認(rèn)編碼爬立。

四、情況3:Get方法生成的URL包含漢字

前面說(shuō)的是直接輸入網(wǎng)址的情況万哪,但是更常見(jiàn)的情況是侠驯,在已打開的網(wǎng)頁(yè)上,直接用Get或Post方法發(fā)出HTTP請(qǐng)求奕巍。

根據(jù)臺(tái)灣中興大學(xué)呂瑞麟老師的試驗(yàn)吟策,這時(shí)的編碼方法由網(wǎng)頁(yè)的編碼決定,也就是由HTML源碼中字符集的設(shè)定決定的止。

<meta http-equiv="Content-Type" content="text/html;charset=xxxx">

如果上面這一行最后的charset是UTF-8檩坚,則URL就以UTF-8編碼;如果是GB2312冲杀,URL就以GB2312編碼效床。

舉例來(lái)說(shuō),百度是GB2312編碼权谁,Google是UTF-8編碼。因此憋沿,從它們的搜索框中搜索同一個(gè)詞"春節(jié)"旺芽,生成的查詢字符串是不一樣的。

百度生成的是%B4%BA%BD%DA辐啄,這是GB2312編碼采章。

圖片.png

Google生成的是%E6%98%A5%E8%8A%82,這是UTF-8編碼壶辜。

圖片.png

所以悯舟,結(jié)論3就是,GET和POST方法的編碼砸民,用的是網(wǎng)頁(yè)的編碼抵怎。

五、情況4:Ajax調(diào)用的URL包含漢字

前面三種情況都是由瀏覽器發(fā)出HTTP請(qǐng)求岭参,最后一種情況則是由Javascript生成HTTP請(qǐng)求反惕,也就是Ajax調(diào)用。還是根據(jù)呂瑞麟老師的文章演侯,在這種情況下姿染,IE和Firefox的處理方式完全不一樣。

舉例來(lái)說(shuō)秒际,有這樣兩行代碼:

url = url + "?q=" +document.myform.elements[0].value; // 假定用戶在表單中提交的值是"春節(jié)"這兩個(gè)字

http_request.open('GET', url, true);

那么悬赏,無(wú)論網(wǎng)頁(yè)使用什么字符集狡汉,IE傳送給服務(wù)器的總是"q=%B4%BA%BD%DA",而Firefox傳送給服務(wù)器的總是"q=%E6%98%A5%E8%8A%82"闽颇。也就是說(shuō)盾戴,在Ajax調(diào)用中,IE總是采用GB2312編碼(操作系統(tǒng)的默認(rèn)編碼)进萄,而Firefox總是采用utf-8編碼捻脖。這就是我們的結(jié)論4。

六中鼠、Javascript函數(shù):escape()

好了可婶,到此為止,四種情況都說(shuō)完了援雇。

假定前面你都看懂了矛渴,那么此時(shí)你應(yīng)該會(huì)感到很頭痛。因?yàn)楸共瑢?shí)在太混亂了具温。不同的操作系統(tǒng)、不同的瀏覽器筐赔、不同的網(wǎng)頁(yè)字符集铣猩,將導(dǎo)致完全不同的編碼結(jié)果。如果程序員要把每一種結(jié)果都考慮進(jìn)去茴丰,是不是太恐怖了达皿?有沒(méi)有辦法,能夠保證客戶端只用一種編碼方法向服務(wù)器發(fā)出請(qǐng)求贿肩?

回答是有的峦椰,就是使用Javascript先對(duì)URL編碼,然后再向服務(wù)器提交汰规,不要給瀏覽器插手的機(jī)會(huì)汤功。因?yàn)镴avascript的輸出總是一致的,所以就保證了服務(wù)器得到的數(shù)據(jù)是格式統(tǒng)一的溜哮。

Javascript語(yǔ)言用于編碼的函數(shù)滔金,一共有三個(gè),最古老的一個(gè)就是escape()茬射。雖然這個(gè)函數(shù)現(xiàn)在已經(jīng)不提倡使用了鹦蠕,但是由于歷史原因,很多地方還在使用它在抛,所以有必要先從它講起钟病。

實(shí)際上,escape()不能直接用于URL編碼,它的真正作用是返回一個(gè)字符的Unicode編碼值肠阱。比如"春節(jié)"的返回結(jié)果是%u6625%u8282票唆,也就是說(shuō)在Unicode字符集中,"春"是第6625個(gè)(十六進(jìn)制)字符屹徘,"節(jié)"是第8282個(gè)(十六進(jìn)制)字符走趋。

圖片.png

它的具體規(guī)則是,除了ASCII字母噪伊、數(shù)字簿煌、標(biāo)點(diǎn)符號(hào)"@ * _ + - . /"以外,對(duì)其他所有字符進(jìn)行編碼鉴吹。在\u0000到\u00ff之間的符號(hào)被轉(zhuǎn)成%xx的形式姨伟,其余符號(hào)被轉(zhuǎn)成%uxxxx的形式。對(duì)應(yīng)的解碼函數(shù)是unescape()豆励。

所以夺荒,"Hello World"的escape()編碼就是"Hello%20World"。因?yàn)榭崭竦腢nicode值是20(十六進(jìn)制)良蒸。

圖片.png

還有兩個(gè)地方需要注意技扼。

首先,無(wú)論網(wǎng)頁(yè)的原始編碼是什么嫩痰,一旦被Javascript編碼剿吻,就都變?yōu)閡nicode字符。也就是說(shuō)串纺,Javascipt函數(shù)的輸入和輸出和橙,默認(rèn)都是Unicode字符。這一點(diǎn)對(duì)下面兩個(gè)函數(shù)也適用造垛。

圖片.png

其次,escape()不對(duì)"+"編碼晰搀。但是我們知道五辽,網(wǎng)頁(yè)在提交表單的時(shí)候,如果有空格外恕,則會(huì)被轉(zhuǎn)化為+字符杆逗。服務(wù)器處理數(shù)據(jù)的時(shí)候,會(huì)把+號(hào)處理成空格鳞疲。所以罪郊,使用的時(shí)候要小心。

七尚洽、Javascript函數(shù):encodeURI()

encodeURI()是Javascript中真正用來(lái)對(duì)URL編碼的函數(shù)悔橄。

它著眼于對(duì)整個(gè)URL進(jìn)行編碼,因此除了常見(jiàn)的符號(hào)以外,對(duì)其他一些在網(wǎng)址中有特殊含義的符號(hào)"; / ? : @ & = + $ , #"癣疟,也不進(jìn)行編碼挣柬。編碼后,它輸出符號(hào)的utf-8形式睛挚,并且在每個(gè)字節(jié)前加上%邪蛔。

圖片.png

它對(duì)應(yīng)的解碼函數(shù)是decodeURI()。

圖片.png

需要注意的是扎狱,它不對(duì)單引號(hào)'編碼侧到。

八、Javascript函數(shù):encodeURIComponent()

最后一個(gè)Javascript編碼函數(shù)是encodeURIComponent()淤击。與encodeURI()的區(qū)別是匠抗,它用于對(duì)URL的組成部分進(jìn)行個(gè)別編碼,而不用于對(duì)整個(gè)URL進(jìn)行編碼遭贸。

因此戈咳,"; / ? : @ & = + $ , #",這些在encodeURI()中不被編碼的符號(hào)壕吹,在encodeURIComponent()中統(tǒng)統(tǒng)會(huì)被編碼著蛙。至于具體的編碼方法,兩者是一樣耳贬。

圖片.png

它對(duì)應(yīng)的解碼函數(shù)是decodeURIComponent()踏堡。

轉(zhuǎn)載自:
http://www.ruanyifeng.com/blog/2010/02/url_encoding.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市咒劲,隨后出現(xiàn)的幾起案子顷蟆,更是在濱河造成了極大的恐慌,老刑警劉巖腐魂,帶你破解...
    沈念sama閱讀 211,376評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帐偎,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蛔屹,警方通過(guò)查閱死者的電腦和手機(jī)削樊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)兔毒,“玉大人漫贞,你說(shuō)我怎么就攤上這事∮” “怎么了迅脐?”我有些...
    開封第一講書人閱讀 156,966評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)豪嗽。 經(jīng)常有香客問(wèn)我谴蔑,道長(zhǎng)豌骏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評(píng)論 1 283
  • 正文 為了忘掉前任树碱,我火速辦了婚禮肯适,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘成榜。我一直安慰自己框舔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評(píng)論 6 385
  • 文/花漫 我一把揭開白布赎婚。 她就那樣靜靜地躺著刘绣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挣输。 梳的紋絲不亂的頭發(fā)上纬凤,一...
    開封第一講書人閱讀 49,792評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音撩嚼,去河邊找鬼停士。 笑死,一個(gè)胖子當(dāng)著我的面吹牛完丽,可吹牛的內(nèi)容都是我干的恋技。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼逻族,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蜻底!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起聘鳞,我...
    開封第一講書人閱讀 37,701評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤薄辅,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后抠璃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體站楚,經(jīng)...
    沈念sama閱讀 44,143評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評(píng)論 2 327
  • 正文 我和宋清朗相戀三年搏嗡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了源请。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡彻况,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出舅踪,到底是詐尸還是另有隱情纽甘,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評(píng)論 4 329
  • 正文 年R本政府宣布抽碌,位于F島的核電站悍赢,受9級(jí)特大地震影響决瞳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜左权,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評(píng)論 3 313
  • 文/蒙蒙 一皮胡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赏迟,春花似錦屡贺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至糕再,卻和暖如春量没,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背突想。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工殴蹄, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人猾担。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓袭灯,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親垒探。 傳聞我的和親對(duì)象是個(gè)殘疾皇子妓蛮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 一、問(wèn)題的由來(lái) URL就是網(wǎng)址圾叼,只要上網(wǎng)蛤克,就一定會(huì)用到。 一般來(lái)說(shuō)夷蚊,URL只能使用英文字母构挤、阿拉伯?dāng)?shù)字和某些標(biāo)點(diǎn)符...
    videring閱讀 305評(píng)論 0 0
  • 每個(gè) Web 開發(fā)者都應(yīng)該知道的關(guān)于 URL 編碼的知識(shí) 原文地址:https://www.oschina.net...
    藍(lán)色緣分1021閱讀 1,138評(píng)論 0 4
  • 一、姓名存儲(chǔ)和展現(xiàn) 1. 按學(xué)生總表編碼存儲(chǔ) 李洋薛鵬磊按照學(xué)生總表進(jìn)行編碼惕鼓,并將編碼進(jìn)行存儲(chǔ)或者發(fā)送 左邊是客戶...
    果芽軟件閱讀 5,111評(píng)論 0 0
  • 一筋现、問(wèn)題的由來(lái) URL就是網(wǎng)址,只要上網(wǎng)箱歧,就一定會(huì)用到矾飞。 一般來(lái)說(shuō),URL只能使用英文字母呀邢、阿拉伯?dāng)?shù)字和某些標(biāo)點(diǎn)符...
    Jedore閱讀 896評(píng)論 0 0
  • 以前也愛(ài)喝酒 擲流離身于一角昏沉燈火下 借酒消愁 談古論今 無(wú)濟(jì)于事洒沦,圖一荒唐 這年頭 得意的人不諳情趣 與失意的...
    谷騰飛閱讀 178評(píng)論 0 0