標籤:des http 使用 os io 資料 for 問題
HTTP POST GET本質區別詳細
一原理區別
一般在瀏覽器中輸入網址訪問資源都是通過GET方式;在FORM提交中,可以通過Method指定提交方式為GET或者POST,預設為GET提交。
Http定義了與服務互動的不同方法,最基本的方法有4種,分別是:GET, POST, PUT, DELTE
URL全稱是資源描述符。我們可以這樣認為:一個URL地址,它用於描述一個網路上的資源,而HTTP中的GET, POST, PUT, DELETE就對
應著這個資源的查,改,增,刪4個操作。到這裡,大家應該有個大概的瞭解了,GET一般用於擷取/查詢資源資訊,而POST一般用於
更新資源資訊(個人認為這是GET和POST的本質區別,也是協議設計者的本意,其它區別都是具體表現形式的差異)。
根據HTTP規範,GET用於資訊擷取,而且應該是安全和等冪的。
1、所謂安全的意味著該操作用於擷取資訊而非修改資訊。換句話說:GET請求一般不會產生副作用。就是說,它僅僅是擷取資源資訊,
就像資料庫查詢一樣,不會修改,增加資料,不會影響資源的狀態。
*注意:這裡安全的含義僅僅是指非修改資訊。
2、等冪的意味著對同一URL的多個請求應該返回同樣的結果。這裡我再解釋一下等冪的這個概念:
(等冪idempotent)是一個數學或電腦概念,常見於抽象代數中。
等冪有以下幾種定義:對於單目運算子,如果在一個運算範圍內的一個數多次進行該運算所得的結果
和進行一次該運算所得的結果是一樣的。那麼我們就稱該運算是等冪的。比如:絕對值就是一個例子。
在實數集中,有abs(a) = abs(abs(a));
對於雙目運算,則要求當參與運算的兩個值是等值的情況下,如果滿足運算結果與參與運算的兩個值相等,
則稱該運算等冪,如求兩個數的最大值的函數,有在實數集中等冪,即:max(x, x) = x;
看完上述解釋後,應該可以理解GET等冪的含義了。
但在實際應用中,以上兩條規定並沒有這麼嚴格。引用別人文章的例子:比如,新聞網站的頭版不斷更新。雖然第二
次請求會返回不同的一批新聞,該操作仍然被認為是安全的和等冪的。因為它總是返回當前的新聞。從根本上說,如果
目標是當使用者開啟一個連結時,他可以確信從自身的角度來看沒有改變資源即可。
根據HTTP規範,POST表示可能修改伺服器上的資源的請求。
繼續引用上面的例子:還是以新聞網站為例,讀者對新聞發表自已的評論應該通過POST實現,因為在評論提交後網站
和資源已經不同了,或者說資源被修改了。
上面大概說了一下HTTP規範中,GET和POST的一些原理性的問題。但在實際做的時候,很多人卻沒有按照HTTP規範去做,導致
這個問題的原因很多,比如說:
1、很多人貪方便,更新資源時用了GET,因為用POST必須要到FROM(表單),這樣會麻煩一點。
2、對資源的增、刪、改、查操作,其實都可以通過GET/POST完成,不需要用到PUT和DELETE
3、另外一個是,早期的Web MVC架構設計者們並沒有有意識地將URL當作抽象的資源來看待和設計。還有一個較為嚴重的問題
是傳統的Web MVC架構基本上都只支援GET和POST兩種HTTP方法,而不支援PUT和DELETE方法。
*簡單解釋一下MVC:MVC本來是存在於Desktop程式中的,M是指資料模型,V是指使用者介面,C則是控制器。使用MVC的目的是將
M和V的實現代碼分離,從而使同一個程式可以使用不同的表現形式。
以上3點典型地描述了老一套的風格(沒有嚴格遵守HTTp規範),隨著架構的發展,現在出現REST(Representational State Transfer)
這裡不多說了,可以參考<<RESTful Web Service>>
二、表現形式區別
搞清了兩者的原理區別,我們再來看一下他們實際應用中的區別:為了理解兩者在傳輸過程中的不同,我們先看一下HTTP協議的格式:
HTTP請求:
<request line>
<headers>
<blank line>
<request-body>]
在HTTP請求中,第一行必須是一個請求行(request line),用來說明請求類型、要訪問的資源以及使用的HTTP版本。
緊接著是一個首部(header)小節,用來說明伺服器要使用的附加資訊。在首部之後是一個空行,再此之後可以添加
任意的其他資料(稱之為主體(body)).
GET與POST方法執行個體:
GET/books/?sex=man&name=Professional HTTP/1.1
Host: www.wrox.com
User_Agent: Mozilla/5.0(Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive
POST/ HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0(Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Content-Type:application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley
有了以上對HTTP請求的瞭解和樣本,我們來看兩種提交方式的區別:
(1)GET提交,請求的資料會附在URL之後(就是把資料放置在HTTP協議頭中),以?分割URL和傳輸資料,
多個參數用&串連;例如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD
如果資料是英文字母/數字,原樣發送,如果是空格,轉換為+;如果是中文/其他字元,則直接把字串用
BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX為該符號以16進位表示的ASCII碼。
POST提交:把提交的資料放置在HTTP包的包體中。上文樣本中紅色字型標明的就是實際的傳輸的資料。
因此,GET提交的資料會在地址欄中顯示出來,而POST提交,地址欄不會改變。
(2)傳輸資料的大小:首先聲明:HTTP協議沒有對傳輸的資料大小進行限制,HTTP協議規範也沒有對URL長度進行限制。
而在實際開發中存在的限制主要有:
GET:特定瀏覽器和伺服器對URL長度有限制,例如IE對URL長度的限制是2083位元組(2K+35)對於其他瀏覽器,如Netscape,FireFox等,
理論上沒有長度限制,其限制取決於作業系統的支援。
因此對於GET提交時,傳輸資料就會受到URL長度的限制。
POST:由於不是通過URL傳值,理論上資料不受限。但實際各個WEB伺服器會規定對POST提交資料大小進行限制,Apache,IIS6都有各自的配置。
(3)安全性
.POST的安全性要比GET的安全性高。注意:這裡所說的安全性和上面GET提到的“安全”不是相同的概念。上面的“安全”的含義僅僅是不作資料修改。
而這裡安全的含義是真正的Security的含義。比如:通過GET提交數制,使用者名稱和密碼交明文出現在URL上,因為(a)登入頁面有可能被瀏覽器緩衝,
(b)其他人查看瀏覽器的記錄,那麼別人就可以拿到你的帳號和密碼了,除此之外,使用GET提交資料還可能會造成Cross-site rquest forgerr攻擊。
(4)Http get, post, soap協議都是在http上啟動並執行
(a)get:請求參數是作為一個key/value對的序列(查詢字串)附加到URL上的,查詢字串的長度受到Web瀏覽器和Web伺服器的限制(如IE最多支援2048個字元)
不適合傳輸大型資料集,同時它很不安全。
(b)post:請求參數是在http標題的一個不同部分(名為entity body)傳輸的,這一部分用來傳輸表單資訊,因此必須將Content-type設定為:application/x-www-form-url-encoded。
post設計用來支援web表單上的使用者欄位,其參數也是作為key/value對傳輸。
但是:它不支援複雜資料類型,因為post沒有定義傳輸資料結構的語義和規則。
(c)soap:協議是http post的一個專用版本,遵循一種特殊的xml訊息格式,Content-type設定為text/xml,任何資料都可以xml化。
三HTTP響應
1、HTTP響應格式:
<status line>
<headers>
<blank line>
[<response-body>]
在響應中唯一真正的區別在於第一行中用狀態資訊代替了請求資訊。狀態行(status line)通過提供一個狀態代碼
來說明所請求的資源情況。
HTTP響應執行個體:
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type:text/html;charset=ISO-8859-1
Content-Length:122
<html>
<head>
<title>Wrox Homepage</title>
</head>
<body>
<!--body goes here-->
</body>
</html>
2、最常用的狀態代碼有:
。200(OK):找到該資源,並且一切正常。
。304(NOT MODIFIED)該資源在上次請求之後沒有任何修改。這通常用於瀏覽器的緩衝機制。
。401(UNAUTHORIZED):用戶端無權訪問該資源。這通常會使得瀏覽器要求使用者輸入使用者和密碼,以登入到伺服器。
。403(FORBIDDEN):用戶端未能獲得授權。這通常是在401之後輸入了不正確的使用者名稱或密碼。
。404(NOT FOUND):在指定的位置不存在所申請的資源。
四完整樣本:
例子:
HTTP GET
發送
GET /DEMOWebServices2.8/Service.asmx/CancelOrder?userID=string&PWD=string&OrderConfirmation String HTTP/1.1
Host: api.efxnow.com
回複:
HTTP/1.1 200OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<ObjPlanceOrderResponse xmlns="https://api.efxnow.com/webservices2.3">
<Success>boolean</Success>
<ErrorDescription>string</ErrorDescription>
<ErrorNumber>int</ErrorNumber>
<CustomerOrderReference>long</CustomerOrderReference>
<OrderConfirmation>string</OrderConfirmation>
<CustomerDealRef>string</CustomerDealRef>
</objectPlaceOrderResponse>
HTTP POST
發送
POST /DEMOWebServices2.8/Service.asmx/CancelOrder HTTP/1.1
Host:api.efxnow.com
Content-Type:application/x-www-form-urlencoded
Content-Length:length
UserID=string&PWD=string&OrderConfirmation=string
回複
HTTP/1.1 200 OK
Content-Type:text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<objPlaceOrderResponse xmlns="https://api.efxnow.com/webservices2.3">
<Success>boolean</Success>
<ErrorDescription>string</ErrorDescription>
<ErrorNumber>int</ErrorNumber>
<CustomerOrderReference>long</CustomerOrderReference>
<OrderConfirmation>string</OrderConfirmation>
<CustomerDealRef>string</CustomerDealRef>
</objPlaceOrderResponse>
SOAP
發送
POST /DEMOWebServices2.8/Service.asmx HTTP/1.1
Host: api.efxnow.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length:length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://wwww.w3.org/2001/XMLSchema=instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<CancelOrder xmlns="https://api.efxnow.com/webservices2.3">
<UserID>string</UserID>
<PWD> string </PWD>
<OrderConfirmation>string</OrderConfirmation>
</CancelOrder>
</soap12:Body>
</soap12:Envelope>
回複:
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length:length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<CancelOrderResponse xmlns="https://api.efxnow.com/webservices2.3">
<CancelOrderResult>
<Success>boolean</Success>
<ErrorDescription>string</ErrorDescription>
<ErrorNumber>int</ErrorNumber>
<CustomerOrderReference>long </CustomerOrderReference>
<OrderConfirmation>string</OrderConfirmation>
<CustomerDealRef>string</CustomerDealRef>
</CancelOrderResult>
</CancelOrderResponse>
</soap12:Body>