您好,登錄后才能下訂單哦!
對于普通的上網過程,系統其實是這樣做的:瀏覽器本身是一個客戶端,當你輸入URL時,首先瀏覽器會去請求DNS服務器,通過DNS獲取相應的域名對應的IP,然后通過IP地址找到IP對應的服務器后,要求建立TCP連接,等瀏覽器發送完HTTP Request(請求)
包后,服務器接收到請求包之后才開始處理請求包,服務器調用自身服務,返回HTTP Response(響應)
包;客戶端接收到來自服務器的響應后開始渲染這個Response包里的主體(body),等收到全部的內容后斷開與該服務器之間的TCP連接。(瀏覽器和服務器交互的過程包含TCP的三次握手和四次揮手)。
如圖,用戶訪問一個Web站點的過程:
Web服務器也被稱為HTTP服務器,它通過HTTP協議與客戶端通信。這個客戶端通常指Web瀏覽器(手機端內部也是瀏覽器實現的)。
Web服務器的工作原理可以簡單歸納為:
注:客戶機與服務器之間的通信是非持久連接的,也就是當服務器發送了應答后就與客戶機斷開連接,等待下一次請求。
URL(Uniform Resource Locator)是"統一資源定位符"的英文縮寫,用于描述一個網絡上的資源,基本格式如下:
scheme://host[:port#]/path/.../[?query-string][#anchor]
scheme 指定底層使用的協議(例如:http, https, ftp等).
host HTTP服務器的IP地址或者域名.
port# HTTP服務器的默認端口是80,這種情況下端口號可以省略。如果使用了別的端口,必須指明,例如 https://amesy.me:8080/
path 訪問資源的路徑.
query-string 發送給http服務器的數據.
anchor 錨.
DNS(Domain Name System)是"域名系統"的英文縮寫,是一種組織成域層次結構的計算機和網絡服務命名系統,被用于TCP/IP網絡,它的功能就是將主機名或域名轉換為實際IP地址。DNS就是這樣的一位“翻譯官”,它的基本工作原理可用下圖來表示:
更詳細的DNS解析的過程如下:
圖示,DNS解析的整個流程:
遞歸查詢:客戶端只發出一次請求一定要得到最終結果;(主機向本地域名服務器的查詢一般都是采用遞歸查詢.)
最后,通過上面的步驟,我們最后獲取的是IP地址,也就是瀏覽器最后發起請求的時候是基于IP來和服務器做信息交互的。
HTTP協議是Web工作的核心,所以要了解清楚Web的工作方式就需要先詳細的了解清楚HTTP是怎樣工作的。
HTTP是一種讓Web服務器與瀏覽器(客戶端)通過Internet發送與接收數據的協議,它建立在TCP協議之上,一般默認采用TCP的80端口。它是一個請求、響應協議,即客戶端發出一個請求,服務器響應這個請求。在HTTP中客戶端總是通過建立一個連接與發送一個HTTP請求來發起一個事務。服務器不能主動去連接客戶端,也不能給客戶端發出一個回調連接。客戶端與服務器端都可以提前中斷一個連接。例如當瀏覽器下載一個文件時,你可以通過點擊"停止"鍵來中斷文件的下載,關閉與服務器的HTTP連接。
HTTP協議是無狀態的,同一個客戶端的這次請求和上次請求是沒有對應關系的,對HTTP服務器來說,它并不知道這兩個請求是否來自同一個客戶端。為了解決這個問題, Web程序引入了Cookie機制來維護連接的可持續狀態。
HTTP協議是建立在TCP協議之上的,因此TCP***一樣會影響HTTP的通訊,例如比較常見的一些***:SYN Flood是當前最流行的DoS(拒絕服務***)與DdoS(分布式拒絕服務***)的方式之一,這是一種利用TCP協議缺陷,發送大量偽造的TCP連接請求,從而使得被***方資源耗盡(CPU滿負荷或內存不足)的***方式。
我們先來看看Request包的結構。Request包分為3部分,第一部分叫Request line(請求行), 第二部分叫Request header(請求頭),第三部分是body(主體)。header和body之間有個空行,請求包的例子所示:
GET /domains/example/ HTTP/1.1 //請求行: 請求方法 請求URI HTTP協議/協議版本
Host:www.iana.org //服務端的主機名
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4 //瀏覽器信息
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 //客戶端能接收的mine
Accept-Encoding:gzip,deflate,sdch //是否支持流壓縮
Accept-Charset:UTF-8,*;q=0.5 //客戶端字符編碼集
//空行,用于分割請求頭和消息體
//消息體,請求資源參數,例如POST傳遞的參數
HTTP協議定義了很多與服務器交互的請求方法,最基本的有4種,分別是GET,POST,PUT,DELETE。一個URL地址用于描述一個網絡上的資源,而HTTP中的GET, POST, PUT, DELETE就對應著對這個資源的查,增,改,刪4個操作。最常見的就是GET和POST。GET一般用于獲取/查詢資源信息,而POST一般用于更新資源信息。
通過fiddler抓包可以看到如下請求信息:
GET信息:
POST信息:
GET和POST的區別
HTTP的Response包的結構如下:
HTTP/1.1 200 OK //狀態行
Server: nginx/1.10.1 //服務器使用的WEB軟件名及版本
Date:Date: Tue, 30 Oct 2012 04:14:25 GMT //發送時間
Content-Type: text/html //服務器發送信息的類型
Transfer-Encoding: chunked //表示發送HTTP包是分段發的
Connection: keep-alive //保持連接狀態
Content-Length: 90 //主體內容長度
//空行 用來分割消息頭和主體
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... //消息體
Response包中的第一行叫做狀態行,由HTTP協議版本號, 狀態碼, 狀態消息三部分組成。
狀態碼用來告訴HTTP客戶端,HTTP服務器是否產生了預期的Response。HTTP/1.1協議中定義了5類狀態碼,狀態碼由三位數字組成,第一個數字定義了響應的類別
下面這個圖展示了一次詳細的資源訪問,可以看到資源狀態返回碼304表示跳轉。response header里面展示了詳細的訪問信息。
HTTP協議是無狀態的和Connection: keep-alive的區別
無狀態是指協議對于事務處理沒有記憶能力,服務器不知道客戶端是什么狀態。從另一方面講,打開一個服務器上的網頁和你之前打開這個服務器上的網頁之間沒有任何聯系。
HTTP是一個無狀態的面向連接的協議,無狀態不代表HTTP不能保持TCP連接,更不能代表HTTP使用的是UDP協議(面對無連接)。
從HTTP/1.1起,默認都開啟了Keep-Alive保持連接特性,簡單地說,當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的TCP連接。
Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同服務器軟件(如Apache)中設置這個時間。
請求實例
上面這張圖我們可以了解到整個的通訊過程,可以看到一個URL請求, 但是左邊欄里面有很多的資源被請求(這些都是靜態文件,go對于靜態文件有專門的處理方式)。
這個就是瀏覽器的一個功能。第一次請求url,服務器端返回的是html頁面,然后瀏覽器開始渲染HTML:當解析到HTML DOM里面的圖片鏈接、css腳本和js腳本的鏈接,瀏覽器就會自動發起一個請求靜態資源的HTTP請求,獲取相應的靜態資源,然后瀏覽器就會渲染出來,最終將所有資源整合、渲染,完整展現在我們面前的屏幕上。
網頁優化方面有一項措施是減少HTTP請求次數,就是把盡量多的css和js資源合并在一起,目的是盡量減少網頁請求靜態資源的次數,提高網頁加載速度,同時減緩服務器的壓力。
參考文檔:https://github.com/astaxie/build-web-application-with-golang
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。