從日常開發說起,淺談HTTP協議是做什麼的

左瀟龍發表於2016-02-07

引言

HTTP協議作為Web開發的基礎一直被大多數人所熟知,不過相信有很多人只知其一不知其二。比如我們們經常用到的session會話機制是如何實現的,可能很多人都說不出來吧。其實session會話就是HTTP協議中的一個header屬性cookie所支援的,在你瞭解了HTTP協議之後,其實這些都非常容易理解。

本文會嘗試從各位的日常開發去解釋一下HTTP到底是做什麼的,文章篇幅有限,如果有什麼本文沒有提到的,各位請自行百度或者看書補腦。接下來,我們們先來看一個小A和小B的故事。

小故事:兩個人的任務

小A和小B是中國著名的網際網路公司BAT的兩個員工,時間走到2015年4月15日下午6點半,北京風沙漫天,彷彿是妖怪來臨,小A和小B興奮的正準備收拾回家,順便享受一下免費的風沙晚餐。

就在這時,專案經理大S的聲音不合時宜的響了起來,“小A,小B,你們倆先別走,給你們倆一個任務”。

兩人聽到這個聲音,苦逼的相視一笑,之後便異口同聲的說道,“頭兒,有事兒您說話”。

“你倆也別不樂意,自從來到BAT,你倆單身問題解決了,房子也買了,存款也有了,加會班也是應該的”。大S注意到二人苦逼的眼神,淡定的說道。看到二人心悅誠服的點了點頭,大S也就不再多說,吩咐道:“我們們專案裡有不少地方需要判斷String是否為空,是否為空串等等,小B你寫一個工具類,小A你把呼叫的地方改一下。”

兩人一聽,這還不簡單,趕緊點頭哈腰的說,“包在我倆身上”。

看到二人的反應,大S滿意的點了點頭,正色說道:“記得我一直教導你們的,bug毀一時,重複毀一生,重構要趁早。”說完這句話,大S便頭也不回的離開二人,數十秒後便鑽進了風沙之中。

小A和小B簡單商量了一下,由小B來編寫String的工具類,小A來呼叫小B的工具類方法。工具類名叫StringUtils,裡面共有兩個方法,一個叫isNull,一個叫isEmpty,引數都是一個String,返回值都是一個boolean。

由於這個類非常簡單,小B很快就搞定了它,程式碼如下。

小B把工具類寫好以後,小A也很快把其中一個用於驗證身份證號的類改成了呼叫小B工具類的方式,程式碼如下。

最後小A又寫了一個簡單的測試類測試了一下,測試類如下。

執行之後,程式執行的結果為正確的,如下。

看到程式很快就正確執行,小A和小B都欣喜不已,感覺自己的技術水平又得到了質的提升。由於兩人住的比較近,於是幹完活之後,二人便一同鑽進了風沙之中。

花絮與故事分析

一個小小的京城故事,兩個快樂的2B程式設計師。沒有複雜的故事情節,沒有高深的技術含量,但卻蘊含著一個像極了WEB資源請求的過程。回想一下剛才小A的程式呼叫小B程式的過程,其實包含了以下三個步驟。

1,小A的程式通過【類名.方法名(引數列表)】的形式找到了小B程式當中的方法。

2,小A的程式傳給小B的程式一個引數,小B的程式對這個請求進行相應的處理,比如判斷是否為空等等。

3,小B的程式根據處理結果返回給小A的程式,小A的程式根據返回結果進行後續的處理。

這整個過程與一個簡單的WEB資源請求如出一撤,具體的內容我們們在接下來的過程中再去討論。這裡,我們們先簡單的回顧一下,小A和小B都商量了哪些東西以後,開始了各自的程式設計。

1,首先小A和小B定義了類名,方法名和引數型別。根據這三個內容,小A就可以通過命名找到小B的兩個方法(比如StringUtils.isNull)。那麼簡單點說,類名,方法名以及引數型別就可以解決“小A怎麼找到小B的方法”。

2,其次,由於規定了小A需要給小B傳送String型別的資料,那麼小B就可以按照String型別進行相應的處理。因此,小A和小B對於方法引數型別的約定,就可以解決“小A傳什麼資料和小B接到以後按照什麼型別去處理”。

3,最後,小B和小A約定返回的型別為boolean,那麼小A這邊收到結果以後就可以按照boolean型別去處理。返回結果的約定,就可以解決“小B返回什麼資料和小A接收到以後按照什麼型別去處理結果”。

HTTP與小故事

一次WEB資源請求的過程,其實就和一次方法呼叫特別相似,上面小A的程式其實就相當於瀏覽器,小B的程式就相當於伺服器,而小B提供的方法就相當於伺服器上的資源。上面我們們分析了方法呼叫的過程,我們們來看看一次WEB資源請求大致分為哪三步。

1,瀏覽器需要根據某種字串格式(類似於故事當中的【類名.方法(引數列表)】的方式)找到伺服器當中的資源。

2,瀏覽器傳給伺服器一個請求,伺服器對這個請求進行相應的處理(比如增刪改查)。

3,伺服器根據處理結果返回給瀏覽器,瀏覽器根據返回結果進行相應的處理(比如顯示網頁,顯示圖片等)。

可以看出,這三個步驟是非常相似的。既然是相似的步驟,那麼就會存在相似的問題。接下來,我們們簡單的分析一下都有哪些問題,以及這些問題如何處理。

【1】如何找到伺服器當中的資源

故事當中,小A根據【類名.方法(引數列表)】的方式找到小B的方法,那麼在WEB資源請求當中,瀏覽器如何找到伺服器的資源呢?

相信大部分人腦子裡已經浮現出了那三個字母。

是的,就是URL。URL就是專門用來定位資源的。URL的一般格式如下。

其中各個部分的含義相信大部分人都知道,這裡我們們就不過多解釋了。最重要的就是protocol,hostname和port,分別代表著應用層的協議(比如http,https,ftp等等),主機名或IP以及服務埠。

【2】瀏覽器和伺服器互相傳輸的資料如何解析

這個問題其實就是第二和第三步所面臨的問題,瀏覽器要給伺服器發請求,但是伺服器哪知道你發的是什麼玩意。同理,如果伺服器給瀏覽器返回資料,瀏覽器同樣也不知道伺服器返回的是什麼東西。

在故事當中,小A和小B商量好了,小A給小B傳String,小B給小A返回boolean,這就很好的解決了程式之間資料交換的解析工作。當然,由於上面的程式非常簡單,所以解析的工作還不是體現的特別明顯。

假設小B的方法是一個save(Map user)的形式,返回值也是一個Map。這時候,如果小B和小A不商量好Map裡面都需要put點啥東西的話,估計這程式也沒法寫下去了。

所以問題就出現在這裡,如果不給瀏覽器和伺服器制定好一個規則的話,不管是開發瀏覽器的程式設計師,還是開發服務的程式設計師,都會出現程式不知道怎麼寫的情況。最可怕的是,開發瀏覽器的程式設計師和開發服務的程式設計師可不一定是同事,他們無法面對面或者通過通訊工具去商量你給我傳什麼,我給你傳什麼這種問題。

所以HTTP協議就應運而生了,這是一群外國人勾搭以後產生的(聽說這群外國人叫World Wide Web Consortium和Internet Engineering Task Force)。HTTP協議自出現以來,主要解決的就是瀏覽器和伺服器資料交換的格式問題。

既然是解決資料交換的格式問題,所以不用去想,也知道HTTP其實是定義了一套資料格式。我們們來看一個實際的例子,一個HTTP請求到底都有哪些資料,以及這些資料是什麼格式。

可以看到,最上面的那一行其實是協議當中定義的首行。第一個GET代表的是,這是一個get請求。後面緊跟著的是訪問的URL,最後是HTTP協議版本。

再往下就是HTTP當中定義的header了,具體每個header都代表什麼意思這裡就不一一解釋了,這不是本文的重點,可以去參考網路上其它的文章。這些Header其實就相當於HTTP協議提供的一些方便的功能,你設定相應的header,可以讓伺服器產生相應的行為。

舉個例子,比如Cookie這個header,大家應該再熟悉不過。它的作用就是告訴伺服器當前請求者的身份,而大部分的伺服器也都會自動去管理Cookie。

除了上面出現的首行和header以外,對於一些特定的請求,HTTP還有特定的資料格式。比如post請求的時候,在【Connection: keep-alive】下面會多出來一個json格式的字串,這個字串就是post請求時所傳送的表單資料。

同樣的,伺服器返回的資料格式也是相似的。一個比較實際的例子如下。

響應當中依然有首行,而首行就是協議版本,加上狀態碼和狀態描述。接下來就是一堆header,這點與請求相同。不同的是,請求和響應所支援的header並不一樣。比如請求的時候,瀏覽器給伺服器傳送Cookie時使用的header是Cookie。但是當伺服器返回響應給瀏覽器時,如果要更新Cookie的話,對應的header是Set-Cookie。最後一行則是伺服器所返回的內容,格式是由Content-Type所指定的,型別為html,字元編碼為UTF-8。對於其它的header這裡就不一一解釋了,請各位自行補腦。

HTTP與WEB開發的聯絡

說到這裡,需要簡單提一下HTTP與WEB開發的聯絡。比如大家在做J2EE開發時所熟知的request和response物件,我們們來看一下request和response介面都有哪些方法。

可以看到,request和response裡面有好幾個方法都和header有關,使用這些方法就可以取到相應的HTTP請求當中的header內容,也可以返回相應的header內容給瀏覽器。還有一點,就是response介面當中定義了一大把狀態碼和狀態描述,比如200對應OK,404對應NOT_FOUND,500對應內部錯誤等等。

可以預見的是,在編寫HttpServletRequest和HttpServletResponse這兩個介面的時候,一定是參照HTTP協議去定義的,而且每當HTTP協議進行一次大的變更,這兩個介面都要跟著進行相應的變化。

總的來說,把對HTTP的瞭解和日常的開發聯絡起來,更加有助於你理解HTTP協議,而且有時候也可以利用HTTP協議擴充套件一些功能,比如授權服務,自定義的狀態保持等等。

小結

到此,大家應該基本上了解HTTP主要是用來做什麼的了,具體HTTP協議當中都規定了哪些內容,大家可以去找各種資料翻閱。個人覺得,只要深刻理解HTTP協議是做什麼的,瞭解一些常用的協議內容就行了,你並不需要把HTTP所有的header都給背下來並記住它們的作用。

最後,重複一下那句與HTTP無關的話:bug毀一時,重複毀一生,重構要趁早。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

從日常開發說起,淺談HTTP協議是做什麼的 從日常開發說起,淺談HTTP協議是做什麼的

相關文章