国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議

這篇具有很好參考價值的文章主要介紹了【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

??作者:一只大喵咪1201
??專欄:《網(wǎng)絡(luò)》
??格言:你只管努力,剩下的交給時間!
【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

??認識HTTP協(xié)議

上篇文章中,本喵帶著大家對HTTP有了一個初步的認識,今天就來詳細講解一下這個應(yīng)用層協(xié)議。

?urlencode和urldecode

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖所示的url(網(wǎng)址),里面包含有/以及?等字符。

  • 像這樣的字符,已經(jīng)被url當做特殊意義理解了,因此這些字符不能隨意出現(xiàn)。

如果url中要包含這些特殊意義的字符,就需要對其做轉(zhuǎn)義處理,就類似C語言中的轉(zhuǎn)義字符一樣。但是這里是網(wǎng)絡(luò),轉(zhuǎn)義的規(guī)則不和C語言一樣,它有自己的規(guī)則:取出字符的ASCII碼:

  • 轉(zhuǎn)成16進制,然后前面加上百分號即可。

比如,+號被轉(zhuǎn)義后成為%2B,這個過程就叫做encode,而將%2B轉(zhuǎn)回到+號就叫做decode。

這個過程并不需要我們自己去做,有需要進行編碼和解碼的需求在網(wǎng)上直接查就可以,URL編碼/解碼。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖,將字符C++進行urlencode后的結(jié)果是C%2B%2B,同樣也可以進行urldecode進行解碼。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
上圖是本喵在百度上搜索C++后跳轉(zhuǎn)到的網(wǎng)頁的URL(網(wǎng)址),可以看到紅色框中的wd=C%2B%2B,其中wd表示關(guān)鍵字,=號后面的內(nèi)容就是encode后的結(jié)果。

當服務(wù)器收到url請求后,會自行對特殊字符%xx進行decode。包括漢字也需要進行encode和decode。

?HTTP協(xié)議宏觀格式

  • HTTP是基于請求和響應(yīng)的應(yīng)用層協(xié)議,使用的是TCP套接字,客戶端向服務(wù)端發(fā)送request請求,服務(wù)端收到請求后會作response響應(yīng)返回給客戶端。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

如上圖所示,是HTTP協(xié)議的宏觀格式,包括客戶端的request和服務(wù)端的response

  • 客戶端:

請求行: 如上圖紅色框中所示,包含GET方法,url,還有http協(xié)議的版本,如http/1.0或者http/1. 1,這三部分構(gòu)成請求行,必須使用\r\n來結(jié)束這一行。

請求報頭: 如上圖綠色框中所示,包含的都是請求屬性,采用的是鍵值對的形式,name表示屬性的名稱,如HOST等,value是屬性的內(nèi)容,如具體的一個網(wǎng)址。每一個屬性必須以\r\n來結(jié)束。

空行: 如上圖紫色框中所示,這一行什么內(nèi)容都沒有,只有\r\n用來表示空行。

請求正文: 如上圖最下面的黑色框中所示,包含請求的正文,如username用戶名,passwd密碼等,同樣每個正文后面必須以\r\n來結(jié)束。

  • 正文可以省略不寫,但是其他三部分必須有,以空行為界,空行后面的是請求正文,空行前面的是請求行和請求報頭。
  • 每一部分都是以字符串形式放在報文中,如GET url http/1.0\r\nname: value\r\n\r\n,這一個報文中,包含請求行,一行屬性以及空行。

請求行和請求報頭兩部分可以看成我們自定義協(xié)議中的報頭,請求正文是有效載荷。

  • 服務(wù)端:

狀態(tài)行: 如上圖紅色框中所示,包含http/1.1HTTP協(xié)議版本,狀態(tài)碼以及狀態(tài)碼描述,最后是\r\n。

響應(yīng)報頭: 如上圖綠色框中所示,包含響應(yīng)屬性,和request的請求報頭類似。

空行: 如上圖紫色框中所示,也是只有一個\r\n。

響應(yīng)正文: 如上圖黑色框中所示,包含服務(wù)器要給客戶端返回的數(shù)據(jù)內(nèi)容,如html/css/js以及圖片,視頻,音頻等網(wǎng)絡(luò)資源。

  • 狀態(tài)行和響應(yīng)報頭同樣類似我們自定義協(xié)議中的報頭,響應(yīng)正文是有效載荷。
  • 服務(wù)端的response和客戶端的request格式相同,只是每一塊的內(nèi)容有所差異。
  • 每一部分中具體名詞的含義后面本喵會講解。

按照上面HTTP協(xié)議的宏觀格式,存在幾個細節(jié)問題:

  1. 應(yīng)用層怎么保證完整的讀取了一個請求或者響應(yīng)?

首先肯定可以完整的讀完一行,因為每一行都是以\r\n結(jié)尾的,所以使用while(完整讀取一行)的循環(huán)可以讀完請求行+請求報頭,直到空行再停止。

按照我們自定義協(xié)議中的邏輯,此時報頭(請求行+請求報頭)完全讀完了,還剩下有效載荷(請求正文)。同樣地,在請求報頭中有一個屬性`Content-Length:XXX正文長度``,根據(jù)這個正文長度就可以將所有的請求正文讀取完畢。

此時一個完整的請求request就讀取到了,同樣的方式也可以讀取到一個完整的響應(yīng)response。

  1. 請求和響應(yīng)是怎么做到序列化和反序列化的?

序列化和反序列化是由HTTP自己實現(xiàn)的,因為協(xié)議中的內(nèi)容都是字符串,第一行(請求行/狀態(tài)行) + 請求/響應(yīng)報頭,只要按照\r\n為判斷條件,一直循環(huán)下去,就可以拼接(序列化)或者拆分(反序列化)。

正文不用進行序列化和反序列化,因為它本身就是字符串,根據(jù)Content-Length:XXX正文長度讀取相應(yīng)字節(jié)數(shù)就可以。

??驗證HTTP協(xié)議格式

上面都是本喵在說HTTP是這樣的格式,那么到底是不是呢?下面寫代碼來看一下。

服務(wù)器底層連接代碼仍然用之前TCP套接字寫好的:

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
其他代碼本喵就不截圖了,在本喵文章TCP網(wǎng)絡(luò)通信有詳細講解,這里就直接拿來用了,如上圖所示,handlerEnter是服務(wù)器處理任務(wù)的入口。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

如上圖所示,不一樣的地方還有在增加了一個回調(diào)函數(shù),包裝器類型:using func_t= function<bool(const request& req, response& resp)>。除此之外,類名也變成了httpServe。

重點在于下面的代碼,服務(wù)器是處理任務(wù)的:

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
先在protocol.hpp中定義請求request和響應(yīng)response,如上圖所示,此時請求和響應(yīng)中只有一個string類型的成員變量。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
當服務(wù)器在執(zhí)行handlerEnter的時候,首先從網(wǎng)絡(luò)中讀取數(shù)據(jù),這里假設(shè)recv一次就能完整讀取一個請求(后面再進行優(yōu)化),然后將讀取到的報文完整賦值到請求req的字符串inbuffer中,再通過_func回調(diào)函數(shù)根據(jù)請求req構(gòu)建響應(yīng)resp,再將響應(yīng)發(fā)送到網(wǎng)絡(luò)中。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖所示的DealReq就是服務(wù)器調(diào)用的回調(diào)函數(shù),用來處理請求并構(gòu)建響應(yīng)的,這里本喵暫時僅打印請求reqinbuffer中的內(nèi)容。

  • 該函數(shù)在構(gòu)造服務(wù)器httpServe對象的時候就被作為參數(shù)傳給了構(gòu)造函數(shù),服務(wù)器中的回調(diào)函數(shù)掉的就是該函數(shù)。

由于從網(wǎng)絡(luò)中讀取到的數(shù)據(jù),也就是客戶端的請求request并沒有經(jīng)過反序列化,也沒有去除過報頭,所以此時reqinbuffer中的內(nèi)容就是一個完整的報文(字符串),包括報頭和有效載荷。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

先將我們的服務(wù)端程序運行起來,如上圖序號1所示,然后在windows端打開瀏覽器,在輸入網(wǎng)址的地方輸入http://服務(wù)端公網(wǎng)IP+端口號,如上圖序號2所示,然后訪問這個url

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
此時windows的瀏覽器就是客戶端,當訪問這個url的時候,客戶端就向服務(wù)端發(fā)起了請求,使用的協(xié)議是http協(xié)議。在服務(wù)端將收到的請求完整打印出來,結(jié)果如上圖所示。

  • 打印出來的http請求的格式符合本喵前面介紹的宏觀格式,并且將每一塊中的具體信息都打印了出來。

下面本喵就來介紹一下,http請求中每一行的具體內(nèi)容是什么。

?請求的格式

請求行:

請求行中的內(nèi)容是GET / HTTP/1.1。

  • GET:表示請求方法,后面詳細講解。
  • / :表示url,也就是要訪問服務(wù)器上文件所在的具體路徑。

這里本喵在windows端輸入網(wǎng)址的時候,并沒有指定路徑,所以在客戶端(瀏覽器)的http協(xié)議會將請求路徑默認構(gòu)建成\表示根目錄。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
windows瀏覽器中輸入網(wǎng)址的時候,加上請求地址/a/b/c,如上圖紅色框中所示,在客戶端發(fā)起請求時,服務(wù)端收到的http請求的請求行中也會有相應(yīng)的請求地址。

請求地址中的第一個/就表示根目錄,和默認請求路徑中的根目錄是一個路徑,但是這個根目錄并不是Linux服務(wù)器上的根目錄,而是web根目錄。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖紅色框所示,存在一個目錄wwwroot,這個目錄就是web根目錄,它位于當前服務(wù)端進程所在的當前目錄,所以說,/根目錄可以是任何一個目錄,因為wwwroot可以創(chuàng)建在任何地方。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
windows客戶端發(fā)起請求的時候,輸入網(wǎng)址中的路徑/a/b/c訪問的就是上圖紅色框中所示的c.html文件。

  • HTTP/1.1表示http協(xié)議的版本號是1.1,常用的版本號還有1.0。

之所以在請求行中要包含http協(xié)議的版本號,是為了服務(wù)器能夠合理的給客戶端提供對應(yīng)的服務(wù)。由于客戶端的更新情況不一致,有的是1.0版本的,有的是1.1版本的,此時服務(wù)端根據(jù)請求行中的版本號就能夠給不同版本的客戶端提供不同的服務(wù)。


請求報頭:

請求報頭中包含許多請求屬性,每一條屬性為一行,使用\r\n結(jié)尾。

  • Host:43.143.106.44:8080,表示客戶端所請求服務(wù)端是套接字(IP地址 + 端口號)。
  • Connection: keep-alive,表示長連接,后面詳細講解。
  • Upgrade-Insecure-Requests: 1,表示瀏覽器(客戶端)支持自動將HTTP請求升級到HTTPS請求。在學習了https協(xié)議后才能感受到這一屬性的作用。
  • User-Agent: 相關(guān)信息: 用于表示客戶端的相關(guān)信息。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖所示,User-Agent后面的內(nèi)容包括客戶端的操作系統(tǒng)和使用的瀏覽器等信息。

  • Accept: 相關(guān)信息:表示該請求要請求的資源類型。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
由于本喵使用的是windows端的瀏覽器向服務(wù)端發(fā)起的請求,并且沒有設(shè)置Accept屬性,也就是沒有指定要請求的資源類型,所以瀏覽器默認將http能請求的所有資源類型都加在了Accept屬性中。

  • Accept-Encoding: gzip, deflate:表示客戶端支持兩種encode格式。

服務(wù)器可以根據(jù)客戶端的支持情況采用不同的壓縮算法進行內(nèi)容壓縮。常見的壓縮算法有g(shù)zip和deflate。

  • Accept-Language: zh-CN,zh;q=0.9:表示客戶端支持的語言格式。

請求報頭中的所有屬性都是采用name: val的鍵值對形式,并且是一個字符串。


之后就是一個空行,只有一個\r\n

?響應(yīng)的格式

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
在處理請求構(gòu)建響應(yīng)的函數(shù)DealReq中,先打印出請求的內(nèi)容,和之前一樣。之后開始構(gòu)建響應(yīng),按照HTTP的宏觀格式構(gòu)建響應(yīng):

  • 構(gòu)建狀態(tài)行,包括HTTP版本,狀態(tài)碼,狀態(tài)碼描述,最后以\r\n結(jié)束。
  • 構(gòu)建響應(yīng)報頭,也就是響應(yīng)屬性,這里本喵暫時只寫一個屬性Content-Type: text/html\r\n,暫時不用管它是什么意思。
  • 構(gòu)建空行,只有\r\n但是這個空行必須有。
  • 構(gòu)建響應(yīng)正文:本喵暫時不寫任何響應(yīng)正文。

構(gòu)建好了響應(yīng)response之后就是將其序列化,也就是將這些不同類型的字符串拼接在一起,如上圖綠色框中所示,最后由服務(wù)器發(fā)送到網(wǎng)絡(luò)中。

如何看到服務(wù)器構(gòu)建的響應(yīng)呢?使用一個telnet工具,如果你的Linux服務(wù)器上沒有的話,使用yum下載一個即可。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

  • 使用telnet工具,通過本地環(huán)回的IP地址和端口號向服務(wù)器發(fā)起請求。
  • 鍵盤上按ctrl + 回車,出現(xiàn)telnet>,再按一下回車跳到下一行。
  • 輸入GET / HTTP/1.1,手動輸入請求行,然后按回車。

此時就向服務(wù)端發(fā)起了請求,會收到服務(wù)端的響應(yīng),如上圖綠色框中所示,這部分內(nèi)容就是我們上面代碼中構(gòu)建的響應(yīng)內(nèi)容,可以看到有狀態(tài)行,響應(yīng)報頭,還有空行。

此時我們已經(jīng)驗證了http的請求和響應(yīng)和本喵前面介紹的宏觀合適是相一致的。

??理解HTTP協(xié)議

上面本喵已經(jīng)通過代碼讓大家看到了HTTP的請求和響應(yīng),從而也驗證了HTTP宏觀格式,接下來就對HTTP協(xié)議做一個更深入的理解。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
在請求中增加幾個成員變量,包括請求訪問method,請求的url,請求的http版本httpversion,以及一個請求路徑。

再通過成員函數(shù)parse對請求進行反序列化,首先使用getOneLine讀取請求中的請求行,然后將請求行中的三個字段分離出來。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
創(chuàng)建一個工具類Util,將一些公用的工具類函數(shù)放在里面,如上圖所示,獲取請求一行內(nèi)容的函數(shù)getOneLine就放在里面。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
再在服務(wù)器的處理入口handlerEnter中調(diào)用請求的成員函數(shù)parse進行反序列化。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
在處理請求,構(gòu)建響應(yīng)的函數(shù)DealReq中,將請求行中的三個字段打印出來,由于通過parse已經(jīng)反序列化了,所以直接打印req中的字段成員變量即可。

在構(gòu)建響應(yīng)正文的時候,添加一段html的代碼,如上圖所示,并且將代碼以字符串的形式拼接到響應(yīng)上。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
使用telnet工具向服務(wù)端發(fā)起請求,此時就會得到服務(wù)端的響應(yīng),如上圖所示,包括響應(yīng)正文(html的代碼)。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
在服務(wù)端就可以看到telnet在發(fā)送請求是輸入的請求行中的三個字段,如上圖紅色框中所示。

  • telnet發(fā)起請求后,得到的響應(yīng)正文中的html代碼到底是什么意思呢?

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

windows上的瀏覽器來訪問服務(wù)器,可以得到如上圖所示的一個網(wǎng)頁,網(wǎng)頁中有一個字符串Hello HTTP,而這個字符串在響應(yīng)正文的html代碼中也出現(xiàn)過。

  • 響應(yīng)正文中的html代碼就是一個網(wǎng)頁,是服務(wù)端響應(yīng)給客戶端的一個網(wǎng)頁。
  • Linux中使用telnet得到響應(yīng)正文并沒有被解釋,所以是完整的html代碼,使用Windows的瀏覽器得到響應(yīng)正文會被瀏覽器做解釋,解釋后得到的就是一個網(wǎng)頁。

關(guān)于html的知識,用到的去查一下即可,本喵這里就直接用了。

?服務(wù)器和網(wǎng)頁分離

上面代碼中,服務(wù)器構(gòu)建響應(yīng)正文時,直接將html代碼放在了string resp_body中,這種將前端代碼嵌入到后端代碼中的方式是不妥的,所以要將前端的html代碼和后端分離開來。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖所示,在wwwroot根目錄下創(chuàng)建幾個文件,其中404.htmlindex.html直接位于根目錄中,a.htmlb.hmtl位于wwwroot/test目錄下。

這四個html的文件內(nèi)容不同,表示的網(wǎng)頁也不同,作用也不同。

404.html:

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖代碼所示,當客戶端發(fā)起的請求中url錯誤或者無效時,會將該文件中的內(nèi)容作為響應(yīng)正文返回給客戶端,告知客戶端訪問資源不存在,并且顯示404錯誤。

index.html:

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

如上圖代碼所示,當客戶端發(fā)起的請求中url\時,例如http://127.0.0.1:8080/,此時會將該文件中的內(nèi)容作為響應(yīng)正文給客戶端返回。

因為此時客戶端訪問的就是web根目錄,也就是./wwwroot目錄,所以當用戶訪問根目錄的時候,本喵將該目錄下的index.html作為響應(yīng)返回。

a.htmlh和b.html:

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖代碼所示,當客戶端發(fā)起的請求中url/test/a.html/test/b.html的時候,服務(wù)器就會將這兩個文件的沒人作為響應(yīng)正文返回給客戶端,客戶端就會得到兩個網(wǎng)頁。


上面4個文件中的代碼都是html代碼,如果將文件內(nèi)容響應(yīng)給Windows的瀏覽器,就會以網(wǎng)頁的形式展現(xiàn),這點本喵在前面展示過。

雖然是網(wǎng)頁,但是歸根到底,仍然是存在于Linux服務(wù)器磁盤上的四個文件,只是后綴是.html而已。

所以服務(wù)端要想將文件中的內(nèi)容作為響應(yīng)正文返回給客戶端,就需要將文件中的內(nèi)容讀出來,并且以字符串的形式拼接到響應(yīng)中。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
Util.hpp中再增加一個工具函數(shù),如上圖所示的readFile,該函數(shù)專門用來讀取文件中的內(nèi)容,并且以二進制的方式讀取到緩沖區(qū)buffer中。

  • 必須以二進制的方式,如果以文本的形式讀取圖片就會出現(xiàn)bug。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

如上圖代碼所示,在DealReq中構(gòu)建響應(yīng)時,使用readFile工具函數(shù)讀取請求中用戶所指定路徑中html文件中的內(nèi)容。

如果讀取失敗,說明沒有用戶指定的文件,則讀取404.html文件中的內(nèi)容作為響應(yīng)正文返回給客戶端。

在調(diào)用readFile的時候,會傳入req.path客戶端指定的路徑,以及resp_body,還有req.size,那么pathsize是怎么來的呢?

可以看到,這兩個參數(shù)都是req的成員變量,所以要在httprequest中處理:
【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

獲取客戶端指定路徑:

首先將web根目錄定義出來,如上圖代碼所示的default_root就表示web根目錄。

parse函數(shù)中,先給path賦值為default_rootpath的值為./wwwroot。再拼接請求中的url,例如請求是http://127.0.0.1:8080/test/a.html,將/test/a.html拼接到path中以后就成為./wwwroot/test/a.html。

如果請求中沒有寫url也就是采用默認的/,那么拼接以后path的值就是./wwwroot/表示訪問web根目錄,此時讓其訪問home_page首頁。

獲取html文件大?。?/strong>

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
Linux中存在一個系統(tǒng)調(diào)用stat,就是用來獲取文件大小的,如上圖所示。

參數(shù):

  • path:目標文件的路徑。
  • buf:是一個struct stat類型的自定義變量,它的成員變量就有文件的大小(以字節(jié)為單位)。
  • 返回值:調(diào)用成功返回0,調(diào)用失敗返回-1。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
上圖所示就是struct stat的定義,成員包含很多文件的屬性,如文件的inode,硬鏈接數(shù)等等,而我們需要的就是st_size文件大小。

所以在httpRequest中通過系統(tǒng)調(diào)用stat來獲取文件的大小,如上圖代碼中紫色框所示。

  • 如果文件不存在,就獲取404.html文件的大小。

此時我們前端的網(wǎng)頁以及后端的服務(wù)器都寫好了,接下來就可以運行了。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
在Windows上的瀏覽器訪問根目錄,就會出現(xiàn)上圖大喵咪網(wǎng)址首頁,而在服務(wù)端可以看到這次請求,其中url/,path./wwwroot/index.html

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

用瀏覽器訪問根目錄下的test/a.html,如上圖所示,會得到網(wǎng)頁我是a網(wǎng)頁。同樣可以在服務(wù)端看到url/test/a.html,path是./wwwroot/test/a.html。

訪問b.html和上面一樣,只是最后的文件名不一樣而已。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
當訪問一個不存在的網(wǎng)絡(luò)資源時,就會得到404錯誤的網(wǎng)頁,表示訪問資源不存在。

此時就做到了服務(wù)器和網(wǎng)頁的分離。

?請求方法

請求方法非常多,但是常用的就兩種,分別是GETPOST方法。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
在Windows上的瀏覽器,百度的搜索框?qū)?yīng)的html代碼如上圖所示。我們之所以能夠搜索東西,是因為這個搜索框本質(zhì)上是一個form表單,如上圖紅色框所示。

我們搜索的關(guān)鍵字就填入這個表單中,然后再將表單的內(nèi)容一起通過HTTP協(xié)議發(fā)送請求到服務(wù)端,服務(wù)端再做出相應(yīng)的響應(yīng)。

  • 我們進行數(shù)據(jù)提交的時候,本質(zhì)是前端要通過form表單提交,瀏覽器會自動將form表單中的內(nèi)容轉(zhuǎn)化成為GET/POST方法請求。

GET方法:

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

index.html中增加form表單,如上圖代碼所示,其中action是客戶端提交信息后要服務(wù)端執(zhí)行的動作,本喵這里是讓服務(wù)端執(zhí)行/test/a路徑下的python程序。

method是請求方法,這里本喵設(shè)置為GET方法。

提交的form表單中,第一行是姓名,第二行是密碼,第三行是登錄按鈕。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
在瀏覽器訪問根目錄,也就是在訪問服務(wù)器的index.html文件,如上圖所示。此時是客戶端第一次發(fā)起請求,所以服務(wù)端會將index.html的內(nèi)容返回給客戶端,此時返回的網(wǎng)頁中包含form表單。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖所示,服務(wù)端收到的第一次請求是請求./wwwroot/index.html路徑下的文件。

  • 第一次默認采用GET方法。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
填好姓名和密碼后登陸就會彈出如上圖所示的網(wǎng)頁,此時是客戶端向服務(wù)端發(fā)送的第二次請求。

  • 提交后的action是讓服務(wù)器執(zhí)行/test/a/c.py下的文件,由于不存在,所以返回資源不存在。
  • form表單中的姓名和密碼以xname=damiaomi&ypwd=123456的形式拼接在了url中,如上圖網(wǎng)址中的綠色框。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖是服務(wù)器在客戶端提交form表單后收到的請求,可以看到,表單中的內(nèi)容被拼接到了url中。

POST方法:

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖代碼所示,將index.html中的method改成POST方法,其他內(nèi)容不變。進行前面那樣的操作:

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
第一次發(fā)起請求時同樣訪問服務(wù)端的根目錄,上圖所示的網(wǎng)頁是服務(wù)端給客戶端的第一次響應(yīng),也是包含一個form表單。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
從服務(wù)器中看到,此次請求的方法仍然是GET方法,因為這是第一次請求,我們指定的POST方法是在提交表單時使用的,也就是在第二次請求中使用的。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
輸入姓名密碼后點擊登錄,輸入的內(nèi)容和前面一樣,同樣會出現(xiàn)資源不存在的網(wǎng)頁,原因也是action的文件不存在。

  • 此時form表單中的內(nèi)容沒有拼接到url中,如上圖紅色框中所示。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

如上圖所示是服務(wù)器收到的第二次請求內(nèi)容,可以看到,此時使用的是POST請求方法,url以及path都是截止到action指定的路徑處,如上圖紅色框中所示。

  • form表單中的內(nèi)容以請求正文的形式提交給了服務(wù)器,如上圖橘色框中所示。

通過上面對比我們發(fā)現(xiàn),GET/POST請求方法的區(qū)別在于:

  • GET方法通過url提交參數(shù)。
  • POST方法通過HTTP請求正文提交參數(shù)。

站在客戶端的角度,如果使用GET方法,在提交form表單的時候,內(nèi)容會拼接到url中,在瀏覽器的網(wǎng)址欄中可以看到,如果是賬號密碼的話其他人就能夠直接看到。

如果使用POST方法,在提交form表單的時候,內(nèi)容是通過請求正文提交的,在瀏覽器的網(wǎng)址欄中看不到。

所以,如果提交的數(shù)據(jù)是比較私密的,如賬號密碼等,就使用POST方法,如果無所謂的數(shù)據(jù)就使用POST/GET哪個都行。

  • 本喵并不是說POST方法比GET方法安全,僅僅是POST方法無法直觀的看到提交的數(shù)據(jù)。
  • POST/GET兩種方法都是不安全的。

?常見報頭屬性

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
在使用POST方法發(fā)起HTTP請求后,多了幾個GET方法中沒有的屬性,如上圖所示。

Content-Type: xxx\r\n

表示連接類型,請求和響應(yīng)中都有。

上圖所示的是請求中的Content-Type,由于會用表單提交數(shù)據(jù)所以它的值如上圖紅色框中所示。這是瀏覽器在告訴服務(wù)器,它提交的請求類型是form,服務(wù)器需要按照表單的處理方式來處理。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
上圖所示是響應(yīng)中的Content-Type,本喵在處理請求構(gòu)建響應(yīng)時,響應(yīng)報頭中只有一個屬性Content-Type: text/html\r\n。

由于服務(wù)器響應(yīng)給客戶端瀏覽器的是一個html文件的內(nèi)容,查閱一下Content-Type對照表:

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖紅色框中所示,html對應(yīng)的Content-Type的值必須是text/html,這是在告訴瀏覽器,服務(wù)器給它的響應(yīng)是html類型的數(shù)據(jù),瀏覽器需要按照html的處理方式來解釋。

Content-Length: XXX\r\n

使用POST方法發(fā)起請求時,服務(wù)器收到的請求中就有Content-Length這一屬性,用來表示請求正文的長度,以字節(jié)為單位。

同樣的,在構(gòu)建響應(yīng)的時候,也可以將這屬性作為響應(yīng)報頭加進去,表示響應(yīng)正文的長度,瀏覽器可以自動識別這一屬性。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
DealReq函數(shù)中構(gòu)建響應(yīng)的時候,添加Content-Length: xxx屬性,如上圖紅色框中所示,該屬性的值就是服務(wù)器返回給客戶端的文件大小,存放在req中。

然后將響應(yīng)正文長度屬性拼接到相應(yīng)報頭中,一起發(fā)出去。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
此時使用telnet工具向服務(wù)器發(fā)起請求時,得到響應(yīng)中包含Content-Length,如上圖紅色框中所示。在使用瀏覽器發(fā)起請求時,瀏覽器能自動識別Content-Length這一響應(yīng)屬性,并作相應(yīng)處理。

?Connection: keep-alive

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
此時index.html中有內(nèi)容,有跳轉(zhuǎn)網(wǎng)頁,有圖片,還有表單等等內(nèi)容,如上圖所示。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
瀏覽器訪問根目錄時,得到的網(wǎng)頁中有這么多內(nèi)容,如上圖所示。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
在瀏覽器上本喵只輸入了一次網(wǎng)址,然后回車,但是服務(wù)器上卻收到了多個請求,如上圖所示(本喵僅截圖幾個)。不同請求的urlpath不同。

  • 一個網(wǎng)頁中有多種類型的資源,而一次請求只能獲取一種類型資源。
  • 雖然我們在瀏覽器中只訪問一次,但是瀏覽器會通過多個線程發(fā)起多次請求。
  • 多次請求的多個響應(yīng)共同組成了一個網(wǎng)頁。

我們知道HTTP協(xié)議使用的是TCP網(wǎng)絡(luò)通信那一套,所以客戶端的每一個請求,服務(wù)器都會創(chuàng)建一個套接字。

像上面這種請求,僅訪問一個網(wǎng)頁就會創(chuàng)建多個套接字,會導致套接字資源緊張,所以就出現(xiàn)了長連接的解決方案。

長連接:

  • 一個客戶端對應(yīng)一個套接字,客戶端的一個請求響應(yīng)完后,套接字不關(guān)閉,只有客戶端退出了,或者指定關(guān)閉時,套接字才關(guān)閉。
  • 一個客戶端無論有多少個請求,都通過一個套接字和服務(wù)器進行網(wǎng)絡(luò)通信。

這里本喵僅能從概念上來給大家講解,無法做出具體的實驗現(xiàn)象。

?會話保持(Cookie和Session)

Cookie技術(shù):

假設(shè)訪問CSDN使用的是HTTP協(xié)議。

CSDN在第一次登錄后,之后打開CSDN就不用再進行登陸了。根據(jù)前面學習我們知道,登錄時輸入的信息其實就是form表單,然后將數(shù)據(jù)提交給服務(wù)器,讓服務(wù)器進行鑒權(quán),如果權(quán)限符合就會返回對應(yīng)的響應(yīng)。

  • HTTP實際上是一種無狀態(tài)協(xié)議,每次請求并不會記錄它曾經(jīng)請求了什么。

所以,在第一次登錄CSDN后,在站內(nèi)進行網(wǎng)頁跳轉(zhuǎn)(從一篇文章到另一篇文章)時,理論上需要再次輸入賬號密碼進行登錄,讓服務(wù)器進行鑒權(quán),因為HTTP的每次請求/響應(yīng)之間是沒有任何關(guān)系的。

  • 但我們在使用瀏覽器訪問CSDN的時候發(fā)現(xiàn)并不是這樣的,只需要登錄一次即可。

這是因為瀏覽器在我們第一次登錄CSDN的時候,將我們的賬號密碼等登錄信息保存了下來。

當我們進行網(wǎng)頁跳轉(zhuǎn)或者再次打開CSDN的時候,瀏覽器自動將保存的用戶登錄信息添加到了請求報頭中,并通過HTTP協(xié)議發(fā)送給了服務(wù)器,服務(wù)器進行鑒權(quán)并返回對應(yīng)的響應(yīng)。

  • 登錄還是需要的,只是瀏覽器幫我們做了這個事。
  • 這種技術(shù)就叫做Cookie技術(shù)。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖所示,點擊網(wǎng)址前面的小鎖,可以查看當前瀏覽器正在使用的Cookie。

當我們將上圖中和CSDN有關(guān)的Cookie數(shù)據(jù)刪除后就需重新輸入賬號密碼來登錄了。

  • 用戶在第一次輸入賬號和密碼時,瀏覽器會進行保存(Cookie),近期再次訪問同一個網(wǎng)站(發(fā)送http請求),瀏覽器會自動將用戶信息添加到報頭中推送給服務(wù)器。
  • 這樣只要用戶首次輸入密碼,一段時間內(nèi)將不用再做登錄操作了。

Cookie又分為內(nèi)存級和文件級:

  • 內(nèi)存級Cookie:將信息保存在瀏覽器的緩沖區(qū)中,當瀏覽器被關(guān)閉時,意味著進程結(jié)束,保存的信息也就沒有了,重新打開瀏覽器后還需要重新登錄。
  • 文件級Cookie:將信息保存在文件中,文件是放在磁盤上的,無論瀏覽器怎么打開關(guān)閉,文件中的信息都不會刪除,在之后發(fā)送HTTP請求時,瀏覽器從該文件中讀取信息并加到請求報頭中。

根據(jù)日常使用瀏覽器的情況,我們可以知道,大部分情況下的Cookie都是文件級別的,因為關(guān)閉了瀏覽器下次打開不用再重新登錄。

Cookie文件也是存在我們電腦上的,具體路徑有興趣的小伙伴可以去找一下。


Session:

如果我們電腦上的Cookie文件被不法份子盜取,那么它就能以我們的身份去登錄我們的CSDN,并且進行一些非法操作。

  • 為了保證信息安全,新的做法是將用戶的賬號密碼信息以及瀏覽痕跡等信息保存在服務(wù)器上。
  • 每個用戶對應(yīng)一個文件,這個文件被叫做Session文件,由于存在很多的Session文件,所以給每個文件一個名字,叫做Session id。
  • 服務(wù)器將Session id作為響應(yīng)返回給用戶,此時用戶的Cookie中保存的就是這個id值。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

如上圖所示,當?shù)谝淮蔚卿洉r,瀏覽器的form表單中的用戶信息提交到了服務(wù)器,服務(wù)器創(chuàng)建Session文件并保存用戶信息,然后再生成一個id返回給瀏覽器。

此時瀏覽器的Cookie保存的就是這個id值。當進行站內(nèi)頁面跳轉(zhuǎn)或者再次打開CSDN的時候,瀏覽器自動將CookieSession id加到請求報頭中提交給服務(wù)端。

服務(wù)端收到請求后,拿到請求報頭中的Session id找到對應(yīng)的Session文件進行鑒權(quán),看看身份是否符合。

鑒權(quán)完畢后做出相應(yīng)的響應(yīng)返回給瀏覽器。

  • 服務(wù)端存儲用戶信息的技術(shù)就叫做Session技術(shù)。

為什么新的會話保持(Cookie和Session)技術(shù)能夠提高用戶信息的安全性呢?

  • 服務(wù)端是由專業(yè)的人員維護的,服務(wù)器中存在病毒以及流氓軟件的可能想更小,所以用戶信息在服務(wù)端會更安全。
  • 如果客戶端的Cookie中的Session id被盜用,不法分子使用該id向服務(wù)端發(fā)起請求時,會因為常用IP地址不一樣而被服務(wù)端強制下線,此時只有手里真正有賬號密碼的人才能夠再次登錄。

保證Session安全的策略非常多,有興趣的小伙伴可以自行了解。


寫入Cookie信息:

我們知道,瀏覽器的Cookie信息是服務(wù)端響應(yīng)返回的,所以在我們構(gòu)建響應(yīng)的時候也可以構(gòu)建Cookie信息讓瀏覽器去保存。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

DealReq函數(shù)中構(gòu)建響應(yīng)時,設(shè)置Cookie信息,內(nèi)容是name=123456abc,有效時間是三分鐘,然后加到響應(yīng)報頭中返回給客戶端,如上圖所示。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
使用瀏覽器訪問根目錄的時候,如上圖所示,會得index.html文件表示的網(wǎng)頁,查看該網(wǎng)頁的Cookie信息,可以看到name123456abc,有效時間是3分鐘,和我們在服務(wù)端構(gòu)建響應(yīng)時寫的內(nèi)容一模一樣。

  • 瀏覽器將我們在響應(yīng)中設(shè)置的Cookie內(nèi)容當作了Session id。

真正生成Session id是有一套復雜的算法的,它能夠保證每一個Session文件的id都是獨一無二的。

  • CookieSession兩種技術(shù)共同組成了HTTP的會話保持。

?HTTP狀態(tài)碼

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
本喵在DealReq中構(gòu)建響應(yīng)的時候,狀態(tài)行中的狀態(tài)碼直接寫的200,狀態(tài)碼描述是OK。那么狀態(tài)碼到底有哪些呢?它們代表的意義是什么?

狀態(tài)碼有五種類型,分別以1~5開頭:

狀態(tài)碼 類別 原因短語
1XX informa(信息性狀態(tài)碼) 接收的請求正在處理
2XX Success(成功狀態(tài)碼) 請求正常且處理完畢
3XX Redirection(重定向狀態(tài)碼) 需要進行附加操作以完成請求
4XX Client Error(客戶端錯誤狀態(tài)碼) 服務(wù)器無法處理請求
5XX Server Error(服務(wù)器錯誤狀態(tài)碼) 服務(wù)器處理請求出錯

最常見的一些狀態(tài)碼,如200(OK),404(Not Found),403(Forbidden請求權(quán)限不夠),302(Redirect),504(Bad Gateway)。

重定向狀態(tài)碼(3XX):

這些狀態(tài)碼沒啥好說的,重點說一下重定向。

  • 重定向就是將網(wǎng)絡(luò)請求重新定個方向轉(zhuǎn)到其它位置(跳轉(zhuǎn)網(wǎng)站),此時這個服務(wù)器相當于提供了一個引路的服務(wù)。

相信都有過這樣的經(jīng)歷,打開一個網(wǎng)址以后,自動就彈出一些廣告網(wǎng)頁,這就是一種重定向。

  • 瀏覽器發(fā)送請求給服務(wù)端,服務(wù)端返回一個新的url,并且狀態(tài)碼是3XX,瀏覽器會自動用這個新的url向新地址的服務(wù)端發(fā)起請求。

所以說,重定向是由客戶端完成的,當客戶端瀏覽器收到的響應(yīng)中狀態(tài)碼是3XX后,它就會自動從響應(yīng)中尋找返回的新的url并發(fā)起請求。

重定向又有兩種:

  • 永久重定向:狀態(tài)碼為301。
  • 臨時重定向:狀態(tài)碼為302307。

臨時重定向和永久重定向本質(zhì)是影響客戶端的標簽,決定客戶端是否需要更新目標地址。

如果某個網(wǎng)站是永久重定向,那么第一次訪問該網(wǎng)站時由瀏覽器幫你進行重定向,但后續(xù)再訪問該網(wǎng)站時就不需要瀏覽器再進行重定向了,此時直接訪問的就是重定向后的網(wǎng)站。

而如果某個網(wǎng)站是臨時重定向,那么每次訪問該網(wǎng)站時都需要瀏覽器來幫我們完成重定向跳轉(zhuǎn)到目標網(wǎng)站。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
如上圖代碼所示,在DealReq函數(shù)中構(gòu)建響應(yīng)時,狀態(tài)行中的狀態(tài)碼設(shè)為307,狀態(tài)碼描述為Temporary Redirect,表示臨時重定向。

設(shè)置屬性Location: XXX,其值是重定向后的地址,這里是本喵CSDN的首頁地址。

然后將屬性Location拼接到響應(yīng)報頭中,最后再發(fā)送給客戶端。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux

在瀏覽器中訪問index.html,但是發(fā)起請求后,返回的并不是index.html中的內(nèi)容,而且屬性Location的值所指向的網(wǎng)頁,也就是本喵CSDN的首頁。

【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議,網(wǎng)絡(luò),網(wǎng)絡(luò),http,網(wǎng)絡(luò)協(xié)議,linux
當瀏覽器發(fā)起請求訪問index.html的時候,收到的響應(yīng)中,狀態(tài)碼是307,所以瀏覽器不解釋index.html,而是根據(jù)響應(yīng)報頭中的Location屬性,得到新的url,再向新的url發(fā)起請求,得到新的響應(yīng),也就是本喵的CSDN首頁。

  • 永久重定向無法演示出來,效果和臨時重定向一樣。

??總結(jié)

這篇文章的思路是,先宏觀介紹HTTP協(xié)議的格式,然后通過代碼去驗證這個格式,然后再把驗證結(jié)果中的具體屬性進行講解。一些重點屬性會單獨舉例進行講解。文章來源地址http://www.zghlxwxcb.cn/news/detail-618657.html

到了這里,關(guān)于【網(wǎng)絡(luò)】應(yīng)用層——HTTP協(xié)議的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【計算機網(wǎng)絡(luò)】應(yīng)用層協(xié)議 -- HTTP協(xié)議

    【計算機網(wǎng)絡(luò)】應(yīng)用層協(xié)議 -- HTTP協(xié)議

    協(xié)議。網(wǎng)絡(luò)協(xié)議的簡稱,網(wǎng)絡(luò)協(xié)議是通信計算機雙方必須共同遵守的一組約定,比如怎么建立連接,怎么互相識別等。 為了使數(shù)據(jù)在網(wǎng)絡(luò)上能夠從源頭到達目的,網(wǎng)絡(luò)通信的參與方必須遵守相同的規(guī)則,我們稱這套相同的規(guī)則為協(xié)議(protocol),而協(xié)議最終都需要通過計算機

    2024年02月15日
    瀏覽(27)
  • 【Linux】應(yīng)用層之HTTP協(xié)議

    【Linux】應(yīng)用層之HTTP協(xié)議

    在應(yīng)用層,需要我們傳遞應(yīng)用層所需特殊的數(shù)據(jù)格式,這種數(shù)據(jù)可能是連續(xù)數(shù)據(jù),例如int類型的整形變量,也可能是string類型的字符串,也可能是多個變量構(gòu)成的結(jié)構(gòu)體,那么就意味著我們發(fā)送的數(shù)據(jù)可能是連續(xù)的,也可能是不連續(xù)的,這時為了統(tǒng)一數(shù)據(jù)的解析方法,我們對

    2024年02月12日
    瀏覽(31)
  • 【計算機網(wǎng)絡(luò)】應(yīng)用層——HTTP 協(xié)議(一)

    【計算機網(wǎng)絡(luò)】應(yīng)用層——HTTP 協(xié)議(一)

    個人主頁:兜里有顆棉花糖 歡迎 點贊?? 收藏? 留言? 加關(guān)注??本文由 兜里有顆棉花糖 原創(chuàng) 收錄于專欄【網(wǎng)絡(luò)編程】 本專欄旨在分享學習計算機網(wǎng)絡(luò)的一點學習心得,歡迎大家在評論區(qū)交流討論?? HTTP協(xié)議全稱超文本傳輸協(xié)議,通過瀏覽器和服務(wù)器進行數(shù)據(jù)交互,進行

    2024年01月23日
    瀏覽(29)
  • 計算機網(wǎng)絡(luò) - 應(yīng)用層http協(xié)議 - http報文格式介紹(1)

    計算機網(wǎng)絡(luò) - 應(yīng)用層http協(xié)議 - http報文格式介紹(1)

    本篇認識和理解應(yīng)用層中的http協(xié)議,了解抓包工具并進行使用,認識請求報文與響應(yīng)報文,了解報文中基本鍵值對意思例如:Set-Cookie, 狀態(tài)碼等,如有錯誤,請在評論區(qū)指正,讓我們一起交流,共同進步! 本文開始 ① 根據(jù)輸入的url,在域名系統(tǒng)DNS中進行解析獲取對應(yīng)的服務(wù)

    2024年02月12日
    瀏覽(94)
  • 【Linux】應(yīng)用層協(xié)議:HTTP和HTTPS

    【Linux】應(yīng)用層協(xié)議:HTTP和HTTPS

    每個人都可以很喜歡每個人,但喜歡治不了病,喜歡買不了東西,喜歡不能當飯吃,喜歡很廉價… 1.1 URL的組成 1. 在之前的文章中我們實現(xiàn)了一個網(wǎng)絡(luò)版本的計算器,在那個計算器中揉合了協(xié)議定制以及序列化反序列化的內(nèi)容,我們當時也自己定制了一套協(xié)議標準,比如請求

    2024年02月10日
    瀏覽(17)
  • 「網(wǎng)絡(luò)編程」應(yīng)用層協(xié)議_ HTTP協(xié)議學習及深入理解

    「網(wǎng)絡(luò)編程」應(yīng)用層協(xié)議_ HTTP協(xié)議學習及深入理解

    「前言」文章內(nèi)容大致是應(yīng)用層協(xié)議的HTTP協(xié)議講解。 「歸屬專欄」網(wǎng)絡(luò)編程 「主頁鏈接」個人主頁 「筆者」楓葉先生(fy) 「楓葉先生有點文青病」「句子分享」 俗話說,開弓沒有回頭箭,唯有箭折、箭落、箭中靶子三種結(jié)果而已。 ——江曉英《蘇東坡:最是人間真情味》

    2024年02月13日
    瀏覽(29)
  • 計算機網(wǎng)絡(luò):應(yīng)用層(二) Web與http協(xié)議

    計算機網(wǎng)絡(luò):應(yīng)用層(二) Web與http協(xié)議

    我最近開了幾個專欄,誠信互三! ==== ||| 《算法專欄》::刷題教程來自網(wǎng)站《代碼隨想錄》。||| ==== ||| 《C++專欄》::記錄我學習C++的經(jīng)歷,看完你一定會有收獲。||| ==== ||| 《Linux專欄》::記錄我學習Linux的經(jīng)歷,看完你一定會有收獲。||| ==== ||| 《C#專欄》::記錄我復

    2024年02月03日
    瀏覽(21)
  • 學習網(wǎng)絡(luò)編程No.8【應(yīng)用層協(xié)議之HTTP】

    學習網(wǎng)絡(luò)編程No.8【應(yīng)用層協(xié)議之HTTP】

    北京時間:2023/10/9/13:03,一晃好多天過去了,9月14號的文章終于在昨天發(fā)出去了,也是許久沒有更文了,國慶放假期間由于各種原因,在王者峽谷和鏟子世界遨游的不亦樂乎,有待改善!目前面臨挑戰(zhàn)艱巨,問題很多,在這個空窗期我們需要有一股強大的支撐作為動力,畢竟

    2024年02月08日
    瀏覽(24)
  • 【網(wǎng)絡(luò)】應(yīng)用層——協(xié)議定制 | 序列化和反序列化 | 初識http

    【網(wǎng)絡(luò)】應(yīng)用層——協(xié)議定制 | 序列化和反序列化 | 初識http

    ??作者:一只大喵咪1201 ??專欄:《網(wǎng)絡(luò)》 ??格言: 你只管努力,剩下的交給時間! 在前面本喵已經(jīng)帶大家見識過了 scoket 網(wǎng)絡(luò)通信的樣子,現(xiàn)在開始深入學習網(wǎng)絡(luò)的原理,本喵采取的策略是從頂層往底層講解,也就是從應(yīng)用層到數(shù)據(jù)鏈路層的順序。 我們知道,協(xié)議就是

    2024年02月15日
    瀏覽(28)
  • 應(yīng)用層協(xié)議——http

    應(yīng)用層協(xié)議——http

    雖然我們說,應(yīng)用層協(xié)議是我們自己定的,但實際上,已經(jīng)有一些現(xiàn)成的,又非常好用的應(yīng)用層協(xié)議,供我們直接參考使用。HTTP(超文本傳輸協(xié)議)就是其中之一。 平時我們俗稱的 “網(wǎng)址” 其實就是說的 URL: 這里的登錄信息現(xiàn)在已經(jīng)隱藏起來,改成例如手機登錄、微信登錄

    2024年02月15日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包