1. 程式人生 > >HTTP請求中GET和POST的分析

HTTP請求中GET和POST的分析

近期一位朋友想寫iOS上的應用,打算從微博應用做起,第一步先做一個微部落格戶端出來,然後做一個手機微博應用出來,具體做什麼還不甚清楚,其實是在嘗試中。而我正好在用asio寫網路庫,於是主動提出了承擔web伺服器網路庫的部分,也是為了給我自己封裝的網路庫中增加一個http模組。

http大家都不陌生,每天開啟網頁,位址列前大多數顯示的都是http,當然還有https等等,以前跟rangerlee討論curl的時候有說過post和get,不是很清楚,查閱了眾多文章和資料,有點小懂了。

統一資源定位符(URL,英語 Uniform / Universal Resource Locator 的縮寫)也被稱為網頁地址,是因特網上標準的資源的地址(Address)。其實URL就是代表一個特定地址的因特網標準資源URI

。http請求中的get post put delete就是對這個資源進行 查 增 改 刪 ,有點類似於資料庫中的四大操作。get和post最主要的區別是前者是查詢,後者是修改,get類似於C++中const函式,而post類似於set或者add函式。

原理:

GET

根據HTTP標準,GET用於資訊的獲取,並且是安全和冪等的。

安全:GET操作用於獲取資訊/資源,並非修改資訊/資源。主要表現在不能修改資訊。

冪等:這是一個數學/計算機上的概念。對於單目運算來說,如果一次運算和多次運算的結果是一樣的,則該運算是冪等的,例如:C++中的abs(abs(a)) = abs(a),所以abs函式運算就是冪等的;對於雙目運算,兩個相等的參與運算的值在運算之後的結果仍然等於這個值,則該運算是冪等的,例如:C++中的max(a, a) = a,所以max函式的冪等的。

而GET是在同一個地址下獲取到的資源是相同的,並且沒有改變,所以GET是安全的、冪等的。

不過,有些特殊情況也會認為是冪等的。例如:新聞某入口網站的頭條新聞,可能在不斷的更新,使用者可能在不同的時間看到的內容不盡相同,但是這也認為是冪等的,因為對使用者來說,他們訪問的資源是同一個地址的。

POST

根據HTTP標準,POST用於可能修改伺服器資源的請求。並沒有什麼特殊規定。

例如:最常見的就是留言了,留言完之後頁面會重新整理,不管是整體重新整理還是Ajax區域性重新整理,這時候用的請求就是POST。

表現形式:

HTTP格式為:

<request line>

<headers>

<blank line>

[<request-body>]

先是一個請求行(request line),用來說明請求型別、請求地址、HTTP版本;然後是頭部(headers),用來說明伺服器的一些附加資訊;下來是一個空行(blank line);再下來是資料主體(request-body)。

GET格式

GET / HTTP/1.1
Host: www.cppfans.org
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.10 (KHTML, like Gecko) Chrome/23.0.1262.0 Safari/537.10 AlexaToolbar/alxg-3.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3

POST格式

POST /api/posts/create.json HTTP/1.1
Host: duoshuo.com
Connection: keep-alive
Content-Length: 283
Origin: http://duoshuo.com
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.10 (KHTML, like Gecko) Chrome/23.0.1262.0 Safari/537.10 AlexaToolbar/alxg-3.1
Content-Type: application/x-www-form-urlencoded
Accept: */*
Referer: http://duoshuo.com/cors/index.html?xdm_e=http%3A%2F%2Fjkirin.com&xdm_c=default693&xdm_p=1
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3

以上資料是通過Chrome的元素審查中的Network抓取到的。

1.地址的區別

舉個例子:

百度搜索的地址:

http://www.baidu.com/s?tn=monline_4_dg&ie=utf-8&bs=http&f=8&rsv_bp=1&wd=http+get+post&rsv_sug3=9&rsv_sug1=7&rsv_sug4=325&inputT=2533

Get請求會把資料附在URL之後,以?分割URL和傳輸資料,多個引數用&連線,上述URL地址可以堪為URL是http://www.baidu.com/s,後面的tn=monline_4_dg ie=utf-8 bs=http等都是引數。

遇到空格用+替代,上述URL中的搜尋詞是http get post,而URL表現出來的是wd=http+get+post。

數字和字母原樣不變。wd=http+get+post

中文和其他字元用Base64加密,例如有些URL表現為%D4%E3%A0%BD,其中%XX中XX表示該符號的16進位制ANSII碼。

POST請求:把修改的資料放置在是HTTP包的包體中進行傳送。

Get請求的URL會在位址列中顯示出來,而Post只是修改,並不會改變URL。

2.傳輸資料的限制

HTTP協議對URL長度和傳輸的資料長度沒有任何限制,不過在實際開發中會根據瀏覽器的限制條件做一些規定。

GET:根據瀏覽器和作業系統有一些限制。例如:IE(包含IE核心)瀏覽器的URL限制是2K+35個位元組長度,而其他瀏覽器理論沒有限制,但卻取決於作業系統支援的長度。

POST:理論沒有傳輸資料的限制,但總不能提交一個過大的資料,這樣會很慢,所以Web伺服器一般都會做限制的。

3.安全性

POST的安全性高於GET,這裡是指Security而不是Safe,因為Get的URL可以通過分析得出一些資料出來,還有Cookie和歷史記錄等等都會造成一些惡意攻擊或破解。

好了,關於GET和POST就說這麼多了,下來就是要寫一個處理這些請求的http伺服器了。有人會說為什麼要自己寫,而不是用Apache或者nginx等已經成熟的Web伺服器?因為他們太複雜了,功能繁雜,而我卻不需要這麼多功能,所以我寫一個簡單實用的http server就可以了,不過可以借鑑成熟Web伺服器的主要功能程式碼。敬請期待吧,估計測試和投入使用會時挺長時間的。