HTTP協議--瀏覽器的實現

http和socket的區別:

socket和http都能用於網絡上的通信。

那既然有socket那麼爲什麼需要http呢?

socket一般用於比較即時的通信和實時性較高的情況,最常見的就是QQ,微信等聊天和實時推送。

但是長時間網絡連接耗電量快,對於手機來講,手機網絡情況複雜,進出電梯丟信號,需要實現複雜的重傳。

手機網絡連接是電信運營商的網關,網關不允許長時間連接。

然而http一般用於實時性要求不那麼高的情況,比如信息反饋,圖片上傳,獲取新聞信息。


http是一個無狀態,無連接的協議。只能由客戶端主動發起請求,服務器回送響應。


一個完整的HTTP請求過程,通常有下面7個步驟:

1.建立TCP連接

2.Web瀏覽器向Web服務器發送請求命令

3.Web瀏覽器發送請求頭信息

4.Web服務器應答

5.Web服務器發送應答頭信息

6.Web服務器想瀏覽器發送數據

7.Web服務器關閉TCP連接


一個HTTP請求一般由四部分組成:

1.HTTP請求的方法或動作,比如是GET還是POST請求

2.正在請求的URL,總得知道請求地址是什麼吧

3.請求頭,包含一些客戶端環境信息,身份證信息等

4.請求體,也就是請求正文,請求正文可以包含提交的查詢字符串信息,表單信息等


HTTP請求:

當我們在瀏覽器中輸入一個URL然後回車,就會獲取我們想要的資源。執行起來so easy!得到效果so amazing!

它是怎樣發生的呢?

第一步我們在瀏覽器中輸入baidu.com然後按下回車鍵。



第二步DNS解析出IP地址




解析出來bai.com.com ip地址是220.181.57.217:80


第三步瀏覽器向服務器發送請求。

瀏覽器向220.181.57.217:80發送請求

像“http://baidu.com/”中的斜槓是至關重要的。這種情況下,瀏覽器能安全的添加斜槓。而像“http: //example.com/folderOrFile”這樣的地址,因爲瀏覽器不清楚folderOrFile到底是文件夾還是文件,所以不能自動添加 斜槓。這時,瀏覽器就不加斜槓直接訪問地址,服務器會響應一個重定向,結果造成一次不必要的握手。


第四步瀏覽器向web服務器發送給瀏覽器一個重定向響應


這樣瀏覽器就訪問"https://www.baidu.com/"而不是"http://www.baidu.com/"

(這樣做可能是爲了安全考慮)


第五步瀏覽器跟蹤重定向地址



現在瀏覽器知道“https://www.baidu.com/”是正確的訪問地址,於是它便向它發送請求,並得到了響應,200表示成功。




第六步服務器HTML響應


連接狀態:keep-alive

整個響應體是以gzip壓縮的。


第七步瀏覽器渲染HTML響應


鑲嵌在"https://www.baidu.com"html裏面的內容多要經歷和它一樣的方式獲取



這樣我們就可以通過url獲取從web服務器獲取我們想要的數據。



HTTP協議請求篇

其實在我們整個訪問中瀏覽器涉及到的就是HTTP協議中的請求,簡單來說瀏覽器就是http協議中的請求部分


HTTP協議中請求包括三部分;
請求行,消息報頭,請求正文



請求行以一個方法符號開頭,以空格分開,後面跟着URL和協議版本,格式如下:


Method Request-URL HTTP-Version CRLF



Methon表示請求方法(GET , POST ,DELETE等);
Request-URI是一個統一資源標識符;
HTTP-Version表示請求的HTTP協議版本;
CRLF表示回車和換行(除了作爲結尾的CRLF外,不允許出現單獨的CR或LF字符)。



瀏覽器輸入baidu.com

就是一個請求行:
Get baidu.com HTTP/1.1 CRLF
默認的是Get方式,HTTP版本協議可以在瀏覽器中查看,現在大多數多用的1.1



URL是網絡上的資源定位符
每一個URL都代表唯一一個資源
就可以從web服務器獲取你想要的數據了


瞭解到這裏我們可以:

編寫一個簡單的HTTP客戶端,通過原生的HTTP協議從任意的Web服務器上下載一些數據。

     使用python內置庫httplib,定義一個HTTPClient類,從遠程主機獲取數。

     在fetch()方法中使用HTTP()函數及其他輔助函數(例如putrequest()和putheader())創建了一個虛擬的HTTP客戶端,

      客戶端採用GET服務器獲取資源

      然後設定用戶代理,其值爲當前腳本(__file__)

      Accept表明客戶端可以接受任何類型數據信息。

     此時完成了請求行:

     Get baidu.com HTTP/1.1 CRLF



    python httplib裏面用的是HTTP/1.1版本

    

    官方文檔

發起請求的getreply()方法放在一個try-except塊中。響應通過getfile()方法獲取,然後讀取數據流中的內容。

並且把從服務器獲取類容打印出來


就可以看到從www.baidu.com中獲取的一個網頁



這樣一個http瀏覽器就實現了。

下一篇將實現http服務器


發佈了55 篇原創文章 · 獲贊 22 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章