最近面試被問到get和post的區別,由於以爲這個問題太基礎了,勉強的回答了一下(面試沒過),回去的路上忽然以爲壓根沒弄明白具體的區別是什麼。下面開始分析有不對的地方歡迎指正!php
常見區別:html
這些說法實際上是在某些場景產生的:瀏覽器,單從http協議角度來看,get和post的區別在於傳輸方式不一樣,post只比get多了\r\n和body部分,跟協議自己沒有太大關係。nginx
http協議並未對header和body作長度限制,實際是瀏覽器或服務器程序對url長度進行限制,聽說IE對URL長度會限制在2048個字符內,道理很簡單,太多數據會形成服務器的負擔,何況咱們無需傳遞那麼多參數,瀏覽器暫且不說,咱們來分析一下服務器程序不對數據進行長度限制會怎麼樣。web
拿nginx和php舉例吧,一個http請求到達nginx,nginx經過fastcgi告訴php你該幹活了,phpcgi對http請求進行解析並設置環境變量(cgi程序經過設置環境變量來告訴子進程參數是什麼),咱們作一個誇張的假設:http post body爲1Gb,php最大進程數是1000個,經過腳本不停的發送請求,每一個php進程都包含1Gb的環境變量,這時候1000個進程的上下文切超級龐大,處理速度會超級慢,也會拖垮咱們的服務器,因此http服務器程序基本都會作長度限制,如php、apache均可以在config裏進行配置。面試
這個問題有些難講,在web中post的安全性相對get要高一些,並不表明post就是真正的安全戳這裏,而對於API來講get和post沒什麼區別,安全性在於API程序自己。apache
按照規範get請求只包含header,cookie是瀏覽器實現的功能,瀏覽器發送get請求時cookie會包含在header中。post能夠同時用header和body。瀏覽器
GET結構 GET / HTTP/1.1 Host: www.baidu.com Connection: keep-alive Cache-Control: max-age=0 Accept: text/html; Upgrade-Insecure-Requests: 1 Cookie: __cfduid=xxxx
POST結構 POST / HTTP/1.1 Host: www.baidu.com Connection: keep-alive Cache-Control: max-age=0 Accept: text/html; Upgrade-Insecure-Requests: 1 username=shangxiaopang&xxx=xxx
POST+GET POST /?age=10 HTTP/1.1 Host: www.baidu.com Connection: keep-alive Cache-Control: max-age=0 Accept: text/html; Upgrade-Insecure-Requests: 1 username=shangxiaopang&xxx=xxx
get也可使用body傳參數,這樣並不符合規範,服務器程序也不能理解這種方式,可是能夠本身動手寫一下:
安全
發送請求程序 sprintf(buf,"GETANDPOST /test?hehe=123 HTTP/1.1 \r\n"); Rio_writen(client_fd,buf,strlen(buf)); sprintf(buf,"Host: 127.0.0.1:8898 \r\n"); Rio_writen(client_fd,buf,strlen(buf)); sprintf(buf,"Content-Length: 17 \r\n"); Rio_writen(client_fd,buf,strlen(buf)); sprintf(buf,"Accept: */* \r\n"); Rio_writen(client_fd,buf,strlen(buf)); sprintf(buf,"\r\n"); Rio_writen(client_fd,buf,strlen(buf)); sprintf(buf,"name=shang&age=25"); Rio_writen(client_fd,buf,strlen(buf)); close(client_fd);
下面是服務器程序解析後的數據,代碼就省略了
服務器
---Header--- GETANDPOST /test?hehe=123 HTTP/1.1 Host: 127.0.0.1:8898 Content-Length: 17 Accept: */* ---Header--- request_method : GETANDPOST post_params : name=shang&age=25