http協議中的編碼和解碼

來源:互聯網
上載者:User

標籤:request   工作   ajax   文檔   com   wan   十六進位   編程   本質   

http://www.csdn1 2 3.com/html/itweb/20130730/29422_29378_29408.htm

******************************

一、字元集與文字編碼簡介 

  1. 電腦如何顯示文字

  我們知道,電腦是以二進位的“形式”來儲存和處理資料的,也 就是說,不管我們使用鍵盤進行輸入,還是讓電腦去讀取一個文字檔,電腦得到的原始內容是一些二進位序列,當需要對這些二進位序列進行顯示時,電腦 會依照某種“翻譯機制”(也就是編碼方式),取到這些二進位序列所表示的每個文字的“輪廓描述”(點陣或者向量圖),知道了輪廓,電腦便可以將二進位序 列所表示的實際的文字形狀顯示到螢幕上了,這裡面的思想和用學號來表示一個學生是一樣的。(當然,這裡面具體的知識點會很多,相關知識可以參考《電腦圖 形學》中顯示原理的部分和其他與電腦顯示原理相關的基礎書籍)。

2. 字元集

  將一些自然語言中的字元組成一個集合,並對集合中的每個字元制 定正常化的編碼方式,這個字元的集合和正常化的編碼方式就組成了一個字元集。如ASCII字元集裡麵包括了所有的英文字母,並且指定了這些英文字母的編碼 規則。GB2312字元集裡麵包括了常用的簡體漢字,並且指定了這些簡體漢字的編碼規則。

3. 字元編碼

  字元編碼,就是建立一套自然語言中的“字元”跟電腦能夠儲存 處理的位元的映射的規則,即在一個字元集內,用一個特定的位元表示一個唯一“字元”,類似於學號跟學生的映射關係。為了保證統一性,相容性,國際 上會對“字元”和“內碼”的映射關係指定標準,這樣就有了ASCII、Unicode等標準的編碼方式,詳細的編碼方式請參考字元編碼和其他相關資料。

二、泛意義上的編碼和解碼

1. 為什麼需要編碼

  當資料不利於處理、儲存的時候,就需要對它們進行編碼。如對字元進行編碼是因為自然語言中的字元不利於電腦處理和儲存。對圖片資訊、視頻資訊、聲音資訊進行壓縮、最佳化,將其“格式化”,是為了在保證媒體資源品質的同時,盡量的節省網路頻寬和本機存放區的空間。對URL進行編碼,是為了避免URL解析發生歧義,簡化解碼方式,如:URL採用“&”作為不同參數的分隔字元,假如某個特定的參數的名稱或者值本身就包括分隔字元“&”,如果不將參數中的“&”做編碼轉換,那勢必會增加URL解析的複雜性,提高解析錯誤的機率。

2. 怎麼樣進行編碼和解碼

  根據實際需求的差異,編碼、解碼演算法有可能會很複雜,也有可能非常的簡單,但是從根本上來講,編碼、解碼只是在做翻譯工作,將一種形式的資料翻譯為另一種形式的資料,如,最簡單的編碼、解碼就是相當於從一個Map中根據key尋找value,然後使用value代替實際資料中的key的值。複雜一點兒的編碼如javascript中的encodeURIComponent和decodeURIComponent,encodeURIComponent負責將字串中不符合URL編碼規範的字元轉換為“%”形式的十六進位Unicode內碼序列,decodeURIComponent負責將“%”形式的十六進位Unicode內碼序列轉換為實際的字元。

 

三、HTTP協議中的編碼和解碼

 

1. URL的編碼和解碼

 

  首先,由於URL是採用ASCII字元集進行編碼的,所以如果URL中含有非ASCII字元集中的字元,那就需要對其進行編碼。再者,由於URL中好多字元是保留字,他們在URL中具有特殊的含義。如“&”表示參數分隔字元,如果想要在URL中使用這些保留字,那就得對他們進行編碼。

 

  根據2005年發布的RFC3986“%編碼”規範:對URL中屬於ASCII字元集的非保留字不做編碼;對URL中的保留字需要取其ASCII內碼,然後加上“%”首碼將該字元進行替換(編碼);對於URL中的非ASCII字元需要取其Unicode內碼,然後加上“%”首碼將該字元進行替換(編碼)。由於這種編碼是採用“%”加上字元內碼的方式,所以,有些地方也稱其為“百分比符號編碼”。

 

  雖然“百分比符號編碼”對URL的編碼方式做了詳細的規定,但是實踐中,瀏覽器對於URL的編碼方式還是存在一些差異(主要表現在對非ASCII字元編碼的差異),接下來我們首先展示不同瀏覽器(chrome和IE)對URL編碼

的差異性,然後再對這些差異性做一些客觀的總結和分析。

1) 對URL中的非ASCII字元的編碼,原始URL地址:http://test/wangfengpaopao/王豐,請求方式為直接在瀏覽器地址欄輸入地址,發起請求。

a) chrome

b) IE

可以看出對於路徑中的非ASCII字元,chrome和IE都是按照RFC3986“%編碼”進行編碼的,取的是非ASCII字元的Unicode內碼。

 

2) 對URL參數中的非ASCII字元的編碼,原始URL地址:http://test/wangfengpaopao/王豐?name=王豐,請求方式為直接在瀏覽器地址欄輸入地址,發起請求。

 

  a) chrome和IE11

  

 

  b) IE11以下版本(使用gbk進行解碼)

  

 

可以看出對於查詢參數中的非ASCII字元,chrome及其IE11都是按照都是按照RFC3986“%編碼”進行編碼的,取的是非ASCII字元的Unicode內碼。IE11以下版本直接發送的是非ASCII字元相對應的當前系統預設編碼的內碼。

 

3) 對錶單欄位name的值中的非ASCII字元的編碼,請求地址:http://test/wangfengpaopao/王豐,請求方式為get。

 

  a) Chrome

 

    i. 頁面gbk編碼

    

 

    ii. 頁面utf-8編碼

    

 

  b) IE

 

    i. 頁面gbk編碼

    

 

    ii. 頁面utf-8編碼

    

 

可以看出當通過表單發送get請求時,對於表單欄位內容中的非ASCII,chrome和IE都會採用當前頁面的編碼對其進行“百分比符號”編碼。

 

4) 對錶單欄位name的值中的非ASCII字元的編碼,請求地址:http://test/wangfengpaopao/王豐,請求方式為post,enctype為application/x-www-form-urlencoded。

 

  a) chrome

 

    i. 頁面UTF-8編碼

    

 

    ii. 頁面GBK編碼

    

 

  b) IE

 

    i. 頁面UTF-8編碼

    

 

    ii. 頁面GBK編碼

    

 

可以看出當通過表單發送post請求時,對於表單欄位內容中的非ASCII,chrome和IE都會採用當前頁面的編碼對其進行“百分比符號”編碼。

 

5) 對URL中的非ASCII字元的編碼,原始URL地址:http://test/wangfengpaopao/王豐?name=王豐,請求方式為發起AJAX請求,method為get。

 

  a) Chrome

 

    i. 頁面utf-8編碼

    

 

    ii. 頁面gbk編碼

    

 

  b) IE

 

    i. 頁面utf-8編碼

 

      1. IE6(gbk解碼)

      

 

      2. IE11

      

 

    ii. 頁面GBK編碼

 

      1. IE6(gbk解碼)

      

 

      2. IE11

      

 

可以看出,對於URL中的非ASCII字元,ie6沒有做任何的編碼工作,而chrome和IE11則是按照用表單get請求的方式對URL進行編碼的。

 

6) 對URL中的非ASCII字元的編碼,原始URL地址:http://test/wangfengpaopao/王豐,請求方式為發起AJAX請求,method為post,資料位元name=王豐,content-type為application/x-www-form-urlencoded。

 

  a) Chrome

 

    i. 頁面utf-8編碼

    

 

    ii. 頁面gbk編碼

    

 

  b) IE

 

    i. 頁面utf-8編碼

 

      1. IE6

      

 

      2. IE11

      

 

    ii. 頁面GBK編碼

 

      1. IE6

      

 

      2. IE11

      

 

可以看出,對於使用post發送並且content-type為application/x-www-form-urlencoded的請求,各個瀏覽器都沒有對資料進行“百分比符號”編碼。

 

從上面的實驗結果我們看得出:

 

① 對於URL中的路徑部分,IE和chrome都會統一採用utf-8編碼對URL中的非ASCII字元進行百分比符號編碼。

 

② 對於新開頁面,IE11以下版本不會對URL中的參數部分做編碼,chrome和IE11會採用utf-8編碼對URL中的非ASCII字元進行百分比符號編碼。

 

③ 對於通過表單發起的請求(不管是post還是get方式),IE和chrome都會採用當前頁面的預設編碼對URL參數中的非ASCII字元進行百分比符號編碼。

 

④ 對於AJAX通過get方式發起的請求,IE11和chrome會根據當前頁面的預設編碼對URL參數中的非ASCII字元進行百分比符號編碼。而IE6不會對URL非ASCII表示的路徑資訊和參數資訊進行編碼。

 

⑤ 對於AJAX通過post方式發起的請求,即便設定了application/x-www-form-urlencoded頭資訊,瀏覽器也不會對資料做任何的編碼(或者說瀏覽器不把發送的資料當做URL的一部分)。

 

  不同的瀏覽器在不同情況下處理URL中非ASCII字元的編碼方式可謂是千差萬別,好在瀏覽器對錶單資料的編碼處理是一致的,即:對URL路徑中的非ASCII字元採用UTF-8字元集進行百分比符號編碼;對中的表單資料(包括post時enctype為application/x-www-form-urlencoded),採用頁面預設的編碼字元集進行百分比符號編碼。

 

  對於AJAX發起請求時URL編碼的差異性,我們可以對URL或者資料中的非ASCII字元使用javascript的encodeURIComponent進行編碼,統一編碼方式,簡化伺服器解碼的複雜度。

2. 瀏覽器對不同媒體資源類型(mime-type)的“資源”的解碼

1) 與資源類型和編碼類別型相關的HTTP頭資訊。

  a) 瀏覽器request時攜帶的頭資訊

  

  b) 伺服器response時攜帶的頭資訊

  

  當通過瀏覽器發起一個資源請求,瀏覽器會攜帶Accept頭資訊,標識瀏覽器需要的mime-type,並且指定瀏覽器對不同mime-type的喜好係數q,同時瀏覽器也會發送Accept-Charset頭資訊,標識瀏覽器字元集解碼類型。

  當伺服器返回“符合”瀏覽器需求的資源時,伺服器也會攜帶Content-Type頭資訊,標識返回資源的媒體類型和編碼方式。

 

2) 瀏覽器對不同媒體資源類型的資源的解析過程

 

  不管怎樣,瀏覽器發起一個請求時所攜帶的mime-type資訊只是對伺服器返回資源的一種“期望”,資源本身的mime-type還得用伺服器應答時攜帶的mime-type資訊進行表示。

 

  籠統的講,對於文本類型的資料(html/css/js/xml等),瀏覽器首先會根據資源的Charset,將文字資料流的編碼轉換為與資源的mime-type相對應的解碼器處理資料時所使用的編碼,比如對於javascript檔案,如果文字資料流本身 是GBK編碼的,那就得首先轉為Unicode編碼,然後再交給javascript引擎去解析執行。當然對於不同類型的資源,瀏覽器進行解碼的流程也是不一樣的,下面會用流程圖較詳細的說明下瀏覽器對於HTML、CSS、Javascript的通用的解碼步驟。

 

① 瀏覽器對於HTML文檔的解碼流程

 

② 瀏覽器對於CSS/JS文檔的解碼流程

 

3) AJAX請求中,瀏覽器對“資料”的解碼流程

 

  AJAX請求跟頁面內的有資源屬性source的標籤發起的請求有所不同,從本質來說,AJAX請求得到的資料,瀏覽器都認為它是普通的文字資料流,跟具體的mime-type無關,即便是responseXML這樣的資料,它也是由瀏覽器對responseText進行了XML解析,這與使用javascript對responseText進行XML解析的道理是一樣的。

 

  AJAX解碼的流程

  

 

3. 伺服器對資源的編碼和解碼

 

  弄清了編碼和解碼的原理以及瀏覽器的編解碼流程,伺服器的編碼和解碼可說的已經不多了,將來兵擋,水來土掩而已。要說的是為了避免URL解碼時的各種相容性問題,最好有統一的規範,比如通過介面提交的資料中的非ASCII字元都是用encodeURIComponent進行URL編碼。為了避免瀏覽器對資源進行解碼的相容性,伺服器返回資源時,明確正確的指定Charset資訊也是很重要的,通過response.setContentType("",charset)。

 

  除了熟練使用自己所擅長的程式設計語言以及相對應的架構提供的編解碼相關的方法外,可以參考iconv瞭解具體的編碼轉換原理,參考UCharsetDetector瞭解字元集探測原理。

http協議中的編碼和解碼

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.