《圖解HTTP》閱讀筆記(上)

Accumulate_HangZhou發表於2018-12-20

《圖解HTTP》是一本關於http協議方面的內容詳實易懂的書籍,全書共十一章。本系列文章按章節對本書做一個學習記錄,分上下兩個部分。上篇主要講解http相關的內容,包括歷史、http方法、協議格式、報文結構、首部欄位、狀態碼等相關內容,下篇主要是Web安全相關的內容。

第1章 瞭解web及網路基礎

HTTP(HyperText Transfer Protocol)是一種超文字傳輸協議。傳輸協議我們好理解,那何為超文字?多文件之間相互關聯,就形成了超文字。HTTP就是作為web文件傳輸協議存在的,出現的主要目的是為了解決文字傳輸的難題。

#網路基礎TCP/IP

TCP/IP是HTTP內部的一個子集,通常使用的網路是在TCP/IP協議的基礎上運作的。 TCP/IP協議族非常重要的一點就是分層,也就是經典的五層模型:應用層、傳輸層、網路層、資料鏈路層和物理層。 通過一個流程就可以大致搞明白各個層的作用: 首先,作為傳送端的客戶端在應用層(HTTP協議)發出一個想看某個web頁面的http請求。接著,為了傳輸方便,在傳輸層(TCP協議)把從應用層收到的資料(HTTP請求報文)進行分割,並在各個報文上打上標記序號及埠號後轉發給網路層。在網路層(IP協議),增加作為通訊目的地的MAC地址後轉發給鏈路層。接收端的伺服器,在鏈路層接收到資料,按順序往上層傳送,一直到應用層。 傳送端在層與層之間傳輸資料的時候,每經過一層時必定會被打上一個該層所屬的首部資訊。反之,接收端在層與層傳輸資料時,每經過一層時會把對應的首部去掉。

#三次握手

TCP位於傳輸層,提供位元組流服務,所謂位元組流服務,就是為了傳輸方便,將大塊資料分割成以報文欄位為單位的資料包進行管理。 為了準確無誤的將資料送達目的地,TCP協議採用了三次握手(three-way handshaking)策略。握手過程中,使用了TCP的標誌:SYN(synchronize)和ACK(acknowledgement)。 傳送端首先傳送一個帶SYN標誌的資料包給對方。接收端收到後,回傳一個帶有SYN/ACK標誌的資料包以表示傳達確認資訊。最後,傳送端再回傳一個帶有ACK標誌的資料包,代表握手結束。

#URI和URL

URI(Uniform Resource Identifier)指統一資源識別符號,其實就是用字串標識某一網際網路資源。它是由某個具體的協議方案所表示的,協議方案有:http,ftp,mailto,telnet,file等。 URL(Uniform Resource Locator)表示資源的地點(網際網路上所處的位置),是URI的子集。

第2章 簡單的HTTP協議

HTTP協議規定,請求從客戶端發出,最後伺服器端響應該請求並返回。 請求報文是由請求方法、請求URI、協議版本、可選的請求首部欄位和內容實體構成的。 響應報文由協議版本、狀態碼、用以解釋狀態碼的原因短語、可選的響應首部欄位以及實體構成。 HTTP是一種不儲存狀態,即無狀態的協議。也就是說HTTP不會對之前的請求或者響應的狀態進行記錄和管理。因此才引入Cookie技術解決無狀態的問題。

#持久連線

HTTP的初始版本中,每進行一次HTTP通訊,就要斷開一次TCP連線。下一次HTTP通訊,需要重新進行三次握手建立TCP連線,通訊開銷極大。 因此,HTTP1.1提出了持久連線的方法,只要客戶端或者伺服器端任意一端沒有明確提出斷開連線,則保持TCP連線狀態。 而且,持久連線使得多數請求可以並行傳送,而不需要等到上一個請求響應之後,才能傳送下一個請求。

第3章 HTPP報文內的HTTP資訊

#HTTP報文

用於HTTP協議互動的資訊被稱為HTTP報文,HTTP報文字身是由多行資料構成的字串文字,大致可分為報文首部和報文主體兩塊。 HTTP的報文主體用於傳輸請求,或者響應的實體主體。通常,報文主體等於實體主體,只有當傳輸中進行編碼操作時,實體主體的內容傳送變化,才導致它和報文主體產生差異。

#編碼

HTTP在傳輸資料的時候,可以按照資料原樣直接傳輸,也可以在傳輸過程中通過編碼提升傳輸效率。 內容編碼指明應用在實體內容上的編碼格式,並保持實體資訊原樣壓縮。內容編碼後的實體由客戶端接收並負責解碼。 常用的內容編碼有: gzip,compress,deflate,identity。

第4章 返回結果的HTTP狀態碼

狀態碼的職責是當客戶端向伺服器傳送請求時,描述返回的請求結果。我們需要了解一些常見的狀態碼。 200 OK:表示從客戶端發來的請求在伺服器被正常處理了 301:永久性重定向。表示請求的資源已被分配到了新的URI,以後應使用資源現在所在的URI 302:臨時性重定向。資源已被分配到了新的URI,希望本次能使用新的URI訪問。 304:Not Modified,伺服器資源未改變,可直接使用客戶端未過期的快取。 404:表示伺服器上無法找到請求的資源。 500:該狀態碼錶示伺服器在執行請求時發生了錯誤。

第5章 與HTTP協作的web伺服器

一臺HTTP伺服器利用虛擬主機,可以搭建多個web站點。

#代理

代理是具有轉發功能的應用程式,它接收由客戶端傳送的請求並轉發給伺服器,同時也接收伺服器返回的響應並轉發給客戶端。 使用代理伺服器的理由有:1.利用快取技術減少網路頻寬;2.組織內部針對特定網站的訪問控制;3.獲取訪問日誌,等。 代理轉發伺服器的響應時,快取代理會預先將資源的副本儲存在代理伺服器上,當代理再次接收到對相同資源的請求時,就可以不從源伺服器獲取資源而直接返回之前快取的資源。

#閘道器

閘道器能夠使通訊線路上的伺服器提供非http協議服務。利用閘道器可以提高通訊的安全性。

#隧道

隧道的目的是確保客戶端能與伺服器進行安全的通訊,可以使用SSL等加密手段進行通訊。

第6章 HTTP首部

HTTP協議的請求和響應報文中必須包含HTTP首部。
在請求中,HTTP報文由方法、URI、HTTP版本、HTTP首部欄位等部分構成。
在響應中,HTTP報文由HTTP版本、狀態碼、HTTP首部欄位3部分構成。

#HTTP首部欄位

在眾多報文欄位中,HTTP首部欄位包含的資訊最多,HTTP首部欄位是由首部欄位名和欄位值構成的,中間用冒號分隔,多個值用逗號隔開:
首部欄位名: 欄位值1,欄位值2,欄位值3
HTTP首部欄位根據實際用途被分為4種型別:
1.通用首部欄位
通用首部欄位是指請求報文和響應報文都會使用的首部。
Cache-Control: no-chache // 強制向源伺服器再次認證
Cache-Control: no-store // 不快取請求或響應的任何內容
Cache-Control: max-age = [秒] // 響應的最大Age值
Connection: close // 斷開連線
Connection: Keep-Alive // 持久連線
Date: Tue,03 Jul 2018 // 建立HTTP報文的時間和日期
2.請求首部欄位
Accept: text/html // 可以通知伺服器使用者代理能夠處理的媒體型別及媒體型別的優先順序
Accept-Charset:unicode-1-1 // 通知伺服器使用者代理支援的字符集以及字符集的優先順序
Accept-Encoding: gzip, deflate // 通知伺服器使用者代理支援的內容編碼
Accept-Language: zh-cn,zh // 使用者代理能夠處理的自然語言集
Host: www.baidu.com // 請求資源所處的網際網路主機名和埠號,唯一必要的請求首部欄位
If-Match: '123abc' // 伺服器會對比If-Match的欄位值和資源的ETag(實體標記)值,兩者一致時才會執行請求
If-Modified-Since: // 該欄位指定的日期後,伺服器資源發生了更新,伺服器會接受請求,如果請求的資源都沒有更新過,則返回狀態碼304 Not Modified
User-Agent: // 將建立請求的瀏覽器和使用者代理名稱等資訊傳給伺服器
3.響應首部欄位
Accept-Ranges:bytes/none // 告知客戶端伺服器是否能處理範圍請求
Age: 600 // 告知客戶端源伺服器在多久前建立了響應
ETag: 'abc-123' // 伺服器會為每份資源分配對應的ETag值,當資源更新時,ETag值也會更新。ETag有強ETag和弱ETag之分,強ETag不論實體發生多麼細微的改變都會改變其值;弱ETag只用於提示資源是否相同,只有資源發生了根本改變才會更改ETag值
Location: // Location可以將響應接收方引導至某個與請求URI位置不同的資源,幾乎所有瀏覽器接收到包含Location的響應後,都會強制性嘗試訪問重定向的資源
4.實體首部欄位
Allow: GET,HEAD // 通知客戶端能夠支援的所有HTTP方法
Content-Encoding: gzip // 告知客戶端伺服器對實體主體的編碼方式(壓縮)
Content-Language: zh-CN // 告知客戶端實體主體使用的自然語言
Content-Length: 15000 // 表示實體主體部分的大小(單位是位元組)
Expires: Date() // 告知客戶端資源實效的日期,優先順序小於max-age
Last-Modified: Date() // 指明資源最終修改的時間

#為Cookie服務的首部欄位

響應首部欄位Set-Cookie
Set-Cookie: name=jack // 賦予cookie名稱和值
Set-Cookie: expires=DATE // cookie的有效期
Set-Cookie: domain=域名 // 指定domain後可以在主域名與二級域名之間共享cookie
Set-Cookie: Secure // 僅在HTTPS安全通訊時才傳送cookie
Set-Cookie: HttpOnly // 限制JavaScript指令碼訪問cookie

相關文章