主要內容:
- Web客戶端與服務端是如何通信的
- HTTP報文格式
- 底層TCP網絡傳輸
1.1 Web客戶端和服務端
Web資源都是存儲在Web服務器上的,因為Web服務器使用HTTP通信,以此也成為HTTP服務器。HTTP客戶端發出HTTP請求,服務端會根據客戶端傳輸的數據,作出HTTP響應發送請求的數據。如圖 1-1 所示,HTTP客戶端和HTTP服務端工作原理:
image.png
- Web服務器是Web資源的倉庫,資源包含任意內容:文本文件、HTML文檔、Word文件、圖片、視頻等。但是資源不一定非得是像前面提高的靜態文件,也可以是根據Web應用程序生成的動態內容,比如數據庫中里的數據。
- Web客戶端,瀏覽器是一種我們經常使用到的Web客戶端,其中還可以是手機原生應用、小程序等。也可以說能實現發送HTTP請求的程序都可以是Web客戶端。
1.2 URI
每一個Web服務器資源都有一個名字,這樣客戶端才可以說明它想要的是什么資源。服務器資源名稱被稱為統一資源標識符(Uniform Resource Identifier, URI)。
- URI的一般格式:
<方案名稱>:<分層部分>[? <查詢參數>] [# <片段>]
統一資源定位符(URL)是資源標識符最常見的形式。如圖 1-2 為URL實例:
image.png
1.3 HTTP報文
HTTP是一種請求-響應協議,HTTP報文是由一行一行的簡單字符串組成的,都是純文本,易讀。HTTP報文格式:
- 起始行
報文的第一行,在請求報文中用來說明要做什么,在響應報文中說明出現了什么。 - 首部字段
起始行后面有零個或者多個首部字段。每個字段都包括一個名字和值。兩者之間用冒號(:)分隔。首部以空行結束。 - 主體
空行之后就是可選的報文主體,其中包含了所有類型的數據。
HTTP報文實例:
- 請求報文
GET /index.html HTTP/1.0 起始行
Accept: text/* 首部
Accept-Language: en, fr
- 響應報文
HTTP/1.0 200 OK 起始行
Content-type: text/plain 首部
Content-length: 19
Hi, I am index 主體
1.4 事務
1.4.1 HTTP請求方法
請求方法是起始行中的第一個單詞,指明了客戶端要對資源進行的操作。
常見的HTTP方法:
- GET:命令服務器返回指定資源
- POST:命令服務器將報文主體中的數據傳遞給URI指定的資源。
- PUT:命令服務器將報文主體中的數據設置為URI指定的資源。
- DELETE:命令服務器刪除URI指定資源
1.4.2 HTTP響應
HTTP響應報文是對HTTP請求報文的回復。跟HTTP請求報文一樣,也是一些列的文本組成。
狀態碼:
- 1xx:情報狀態碼。
- 2xx: 成功狀態碼。
- 3xx:重定向狀態碼。
- 4xx:客戶端錯誤狀態碼。
- 5xx:服務端錯誤狀態碼。
一個Telnet實例
GET /index.html HTTP/1.1
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache
Connection: Keep-Alive
Content-Length: 14615
Content-Type: text/html
Date: Mon, 19 Aug 2019 08:57:08 GMT
Etag: "5d54da0d-3917"
Last-Modified: Thu, 15 Aug 2019 04:05:33 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Pragma: no-cache
Server: BWS/1.1
Set-Cookie: BAIDUID=668FD107459E334256837E510A760274:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=668FD107459E334256837E510A760274; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1566205028; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=1
<!DOCTYPE html><!--STATUS OK-->
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<link rel="dns-prefetch" />
<link rel="dns-prefetch" />
<link rel="dns-prefetch" />
<link rel="dns-prefetch" />
<link rel="dns-prefetch" />
<link rel="dns-prefetch" />
<link rel="dns-prefetch" />
<link rel="dns-prefetch" />
<title>百度一下,你就知道</title>
<link rel="stylesheet" type="text/css" />
<!--[if lte IE 8]><style index="index" >#content{height:480px\9}#m{top:260px\9}</style><![endif]-->
<!--[if IE 8]><style index="index" >#u1 a.mnav,#u1 a.mnav:visited{font-family:simsun}</style><![endif]-->
<script>var hashMatch = document.location.href.match(/#+(.*wd=[^&].+)/);if (hashMatch && hashMatch[0] && hashMatch[1]) {document.location.replace("http://"+location.host+"/s?"+hashMatch[1]);}var ns_c = function(){};</script>
<script>function h(obj){obj.style.behavior='url(#default#homepage)';var a = obj.setHomePage('//www.baidu.com/');}</script>
<noscript><meta http-equiv="refresh" content="0; url=/baidu.html?from=noscript"/></noscript>
<script>window._ASYNC_START=new Date().getTime();</script>
</head>
參考文獻:
- 《HTTP權威指南》