WEB 是如何工作的

  • 時間:2018-10-05 23:14 作者:黑貓之家 來源:黑貓之家 閱讀:235
  • 掃一掃,手機訪問
摘要:原本很猶豫能否要寫一下這篇文章的,畢竟自己才疏學淺,說些淺的知識還行,一旦深入,就會漏了馬腳。但是,另一方面想,既然知道自己懂的不夠,就更應該把知道的給梳理出來,也好進行下一步的學習。所以這篇文章也算是對當前所學所知進行一個總結吧,遛。簡解先上一個大概的圖解上圖簡單的解釋了打開一個網頁的過程,略微詳

原本很猶豫能否要寫一下這篇文章的,畢竟自己才疏學淺,說些淺的知識還行,一旦深入,就會漏了馬腳。但是,另一方面想,既然知道自己懂的不夠,就更應該把知道的給梳理出來,也好進行下一步的學習。所以這篇文章也算是對當前所學所知進行一個總結吧,遛。

簡解

先上一個大概的圖解

WEB 是如何工作的

上圖簡單的解釋了打開一個網頁的過程,略微詳細的解釋就是:

  • 瀏覽器得到網址,并把網址拆解為域名和路徑
WEB 是如何工作的

  • 瀏覽器尋覓域名對應的 IP
  • 先在瀏覽器自己的緩存里找,假如之前訪問過,會有緩存
  • 假如沒有緩存,則讓手機或者電腦向 DNS 服務器請求獲取
  • 瀏覽器向服務器請求數據
  • 服務器解析請求,得到請求的路徑參數等
  • 假如是靜態頁面,直接找到對應的靜態文件
  • 假如是動態頁面,調用動態語言解決數據合成頁面,再交給 HTTP 服務器
  • 服務器把頁面發回瀏覽器
  • 瀏覽器得到數據,進行解析、渲染、輸出

最終就看到了網頁。

詳解

從上面的簡解我們可以知道,訪問的過程大概可分為:URL,DNS 查詢,HTTP,瀏覽器,這四個部分。

URL

是什么

URL 是 Uniform Resource Locator 的簡寫,中文:統一資源定位符,在 web 中很多時候被叫做 ‘網址’。

URL 的標準格式如下:

協議:[//地址[:端口]][/路徑]文件[?數據][#錨點]- 協議: 在 web 中通常使用 http,https- 地址: 域名或者者 IP 地址- 端口: 默認情況下,http 使用 80 端口、https 使用 443 端口的時候,可以省略- 路徑: 要訪問資源所在的目錄- 文件: 當請求的是具體一個文件時,比方一張圖片,需要寫清楚,否則由服務器決定返回設置的文件,一般是 `index.html`- 數據: ? 后寫 GET 請求的參數,每個參數以 & 隔開,再以 = 分開參數名稱與數據- 錨點: # 后面的數據不會被發送到服務器,它代表網頁中的一個位置

發生了什么

瀏覽器獲取到客戶輸入的 URL,就按照以上格式進行解析,假如不符合標準格式,則會判斷為客戶輸入了關鍵字,并跳轉到搜索引擎搜索,當 URL 中存在不是 ASCII 的字符串時,會把字符串轉成 punycode 標準編碼的字符串。

獲取到域名后,瀏覽器首先會在瀏覽器的緩存中查找與它相關的資源,比方 DNS 緩存、靜態資源緩存

瀏覽器的 DNS 緩存會把之前訪問過的域名對應 IP 緩存起來,方便下次使用,一般會保存 TTL(DNS 服務器上緩存時間)、Expires(瀏覽器記錄的到期時間)

假如沒有緩存,則進行下一步,DNS 查詢

DNS 查詢

是什么

把網址翻譯成 IP 地址。

比如說你的電腦不知道 www.zhih.me 這個域名的 IP 地址,他就會向 DNS 服務器發送個請求,讓 DNS 服務器幫他尋覓,此時你的電腦就是一個 DNS 用戶端,實際上整個具體過程會有不同的情況。

域名的結構

想要了解 DNS 查詢過程,還得先知道域名的結構。

以 www.zhih.me 這個域名為例,它是個全稱域名(FQDN)

當你看到它時,應當從右往左讀

WEB 是如何工作的

而整個域名系統的結構是這樣的

WEB 是如何工作的

根域:儲存了負責每個域(如com、cn、me等)的解析的域名服務器的地址信息

頂級域名(TLD):分為通用、國家、資助和地理幾種類型,用于表示某些組織或者用途

二級域名(SLD):表示組織、個人、特定意義的名稱

三級域名:例如:sina.com.cn,sina 是一個三級域名,同時又是 com.cn 的子域名

子域名:子域名與三級域名不同,例如:www.zhih.me,www 是 zhih.me 的子域名,但卻不是三級域名

查詢過程

本地解析

  1. 查看 HOSTS 記錄,假如有,直接返回結果
  2. 查看 DNS 緩存,看看它里面是不是有你設置的域名 IP 地址,緩存信息是通過以前的查詢取得的,電腦關機時緩存將會被清空

直接解析

本地找不到,就向你電腦里設置的 DNS 服務器請求,假如沒有設置具體的地址,而是自動獲取,就會從 ISP 中獲取 DNS 服務器的 IP 地址,我自己使用的是騰訊的 DNS 服務器,我們一般把它叫做本地 DNS 服務器

WEB 是如何工作的

當本地 DNS 服務器找不到結果時,就需要跟其余 DNS 服務器查詢獲取

完整解析

WEB 是如何工作的

這個過程可以使用 dig 命令查看

$ dig www.zhih.me +trace

這樣,電腦就拿到域名對應的 IP 地址了

HTTP

關于是什么,在維基百科已經寫的很詳細了,自己看看吧

https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

前面我們已經找到了 IP,那么現在我們就要發送請求和接收響應了

請求方法

方法形容

GET請求指定的頁面信息,并返回實體主體

HEAD相似于get請求,只不過返回的響應中沒有具體的內容,用于獲取報頭

POST向指定資源提交數據進行解決請求(例如提交表單或者者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或者已有資源的修改

PUT從用戶端向服務器傳送的數據取代指定的文檔的內容

DELETE請求服務器刪除指定的頁面

CONNECTHTTP/1.1協議中預留給能夠將連接改為管道方式的代理商服務器

OPTIONS允許用戶端查看服務器的性能。

TRACE回顯服務器收到的請求,主要用于測試或者診斷

HTTP 狀態碼

HTTP狀態碼(HTTP Status Code)是用以表示網頁服務器HTTP響應狀態的3位數字代碼。它由 RFC 2616 規范定義的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等規范擴展。

應該每個網民都不陌生,或者多或者少遇到過 404 not fount

狀態碼有相當多,在這里我就列出他們的分類

類型類別形容

1xx信息請求已被接受,需要繼續解決

2xx成功操作被成功接收并解決

3xx重定向需要用戶端采取進一步的操作才能完成請求

4xx用戶端錯誤請求的參數錯誤或者無法完成請求

5xx服務器錯誤服務器在解決請求的過程中有錯誤或者者異常

HTTP 消息結構

在 shell 中使用 curl -v 命令即可以看到請求和響應的消息了

以最常用的 get 請求為例:

$ curl -v https://mov.zhih.me/weapp/list/1/2
WEB 是如何工作的

HTTP 請求

請求報文的一般包括以下格式:請求行、請求頭部、空行和請求數據

GET /weapp/list/1/2 HTTP/2//請求行: 請求方法 請求URI HTTP協議/協議版本Host: mov.zhih.me//服務端的主機名user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36//瀏覽器 UAaccept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8//用戶端能接收的mineaccept-encoding: gzip, deflate, br//能否支持流壓縮# 空行# 請求數據

請求頭部就是請求行和空行之間的鍵值對

HTTP 響應

響應報文也由四個部分組成,分別是:狀態行、消息報頭、空行和響應正文

HTTP/2 200//狀態行:HTTP協議版本號, 狀態碼, 狀態消息server: nginx/1.14.0//web 服務器軟件名及版本date: Thu, 17 May 2018 14:46:50 GMT//發送時間content-type: application/json; charset=utf-8//服務器發送信息的類型content-length: 589//主體內容長度# 空行 {"code":200,"data":[{"rank":1,"movid":1292052,"rating":9.6,"title":"肖申克的救贖","genres":["犯罪","劇情"],"year":1994,"directors":["弗蘭克·德拉邦特"],"casts":["蒂姆·羅賓斯","摩根·弗里曼","鮑勃·岡頓"],"image":"https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.jpg"},{"rank":2,"movid":1291546,"rating":9.5,"title":"霸王別姬","genres":["劇情","愛情","同性"],"year":1993,"directors":["陳凱歌"],"casts":["張國榮","張豐毅","鞏俐"],"image":"https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1910813120.jpg"}]}% 
//響應正文

服務器

前面說了數據怎樣發送到服務器,現在說說服務器如何解決收到的數據

當然,這部分的情況相當復雜,不同場景有不同的方案,我這里只簡單的舉二三的例子

靜態站點

我的博客 zhih.me 就是個靜態站點,通過模板引擎把數據渲染成靜態 HTML 文件,這些文件就存在服務器上等待下載,瀏覽器獲取頁面就是個文件下載的過程。

  1. 瀏覽器發送 HTTP 請求,請求里包含了文件的路徑、主機名等信息
  2. 我的服務器監聽了 80 和 443 端口,發現有數據傳來,將請求拋給虛擬主機
  3. 虛擬主機發現請求的路徑是 ‘/‘,就把網站根目錄下的 index.html 返回給請求者

動態站點

這里說的動態站點,指頁面是由后臺解決數據合成的

常見的例子就是 WordPress,WP 應該是現在被使用得最多的 CMS 了,它的解決過程應該是這樣的

  1. 瀏覽器發送 HTTP 請求,請求里包含了文件的路徑、主機名等信息
  2. 我的服務器監聽了 80 和 443 端口,發現有數據傳來,發現有數據傳來,將請求拋給虛擬主機
  3. 虛擬主機發現請求的路徑是 ‘/‘,而 ‘/‘ 這個路徑已經指定了 PHP 解決,于是把請求拋給了 index.php 解決
  4. WP 解析請求里的數據,看看有什么參數,你訪問的是首頁,也沒帶什么參數,于是 WP 就從數據庫里把首頁的文章調出來,而后在 PHP 里遍歷合成 HTML 文件,并交給虛擬主機
  5. 虛擬主機把 HTML 頁面返回給請求者

前后分離站點

前后分離是現在和未來的趨勢,大多數 WebApp 都是這種架構,簡單說就是使用 AJAX 獲取數據在用戶端進行渲染。

  1. 獲取靜態資源(靜態站點的整個過程),JS 跑起來后開始請求數據
  2. 后臺程序獲取請求,解析請求數據,從數據庫里提取數據,返回數據
  3. 前臺程序得到數據,遍歷數據,渲染頁面

瀏覽器

前面我們就是從瀏覽器開始的,現在又回到了瀏覽器,瀏覽器是個常用且看似簡單的軟件,但是講真,原理真的挺復雜的,我這里只能說說解析和渲染相關的一點點皮毛知識,如有錯誤歡迎斧正。

打開瀏覽器開發者工具,訪問一個網頁,我們將看到以下信息

WEB 是如何工作的

基本過程是這樣的:

加載 HTML -> 解析 HTML -> 構建 DOM 樹 -> 構建 CSSOM 樹 -> 構建渲染樹 -> 布局、繪制

但是,現代瀏覽器為了更快的顯示頁面,很多任務都是同時進行的,會一邊解析 HTML,一邊下載外部資源,還一邊進行渲染。

解析 HTML 并構建 DOM 樹

瀏覽器自上而下的解析 HTML 文檔,并在解析的同時構建 DOM(文檔對象模型) 樹,DOM 樹里有各個標簽的屬性和它們之間的關系

Critical Path

Hello web performance students!

澳洲幸运10精准人工计划

解釋器深度遍歷 HTML 文檔,把 這些標簽按照 W3C 標準,轉換成 “定義它屬性和規則的對象’”,而后將這些 “對象” 鏈接在樹形結構里,這就是 DOM 樹

WEB 是如何工作的

在以上 HTML 結構例子中,

是兄弟節點,在 DOM 樹的構建過程中,當前節點所有的子節點全都構建完成后才會構建下一兄弟節點

構建 CSSOM 樹

在上面的 HTML 中, 里有個外部樣式表 style.css,HTML 解析到這里時會向服務器請求資源,得到這樣的資源:

body { 
font-size: 16px}p {
font-weight: bold
}span {
color: red
}p span {
display: none
}img {
float: right
}

和解決 HTML 相似,瀏覽器解決 CSS 構建了 CSSOM

WEB 是如何工作的

構建渲染樹

前面已經構建了 DOM 樹和 CSSOM 樹,現在瀏覽器就把它們合并成一個渲染樹

WEB 是如何工作的

在渲染樹的構建過程中,瀏覽器遍歷 DOM 樹,而后對應 CSSOM 樹給每個節點設置計算樣式(最終樣式),設置了 display: none 的節點,將會在渲染樹中移除

這樣,渲染樹就包含了頁面上所有可見的內容和它們的計算樣式

布局、繪制

渲染樹只包含了內容和樣式,要放到瀏覽器窗口中,還需要計算它們在窗口里確實切的位置和大小,這個過程叫做布局,也稱為“自動重排”

瀏覽器從渲染樹的根節點開始遍歷,我們可以想象為有外向里的過程,先確定外層的位置大小,在向里層計算

布局流程的輸出是一個“盒模型”,它會準確地捕獲每個元素在視口內確實切位置和尺寸:所有相對測量值都轉換為屏幕上的絕對像素

布局完成后,瀏覽器會立即發出“Paint Setup”和“Paint”事件,將渲染樹中的每個節點轉換成屏幕上的實際像素,這一步通常稱為“繪制”或者“柵格化”

重排和重繪

當 DOM 或者 CSSOM 被修改時,會發生重排(Reflow),也就是把上面的步驟重新來一遍,這樣才能確定哪些像素需要在屏幕上進行重新渲染,這個過程也被叫做回流

假如改變的屬性與元素的位置大小無關,比方背景顏色,那么瀏覽器只會重新繪制那個元素,這個過程叫重繪(Repaint)

重排必然會引起重繪,重繪則不肯定會重排

CSS、JS 阻塞

默認情況下,CSS 是阻塞渲染的資源,瀏覽器需要等 DOM 和 CSSDOM 都準備好之后才會渲染,注意,這里說的是阻塞渲染,而不是阻塞 DOM 的構建,事實上 DOM 和 CSSDOM 的構建是可以同時進行的

構建 CSSOM 會阻塞它后面 JavaScript 語句的執行,而 JavaScript 語句的執行又會阻止 CSSOM 的構建,起因很簡單,由于 JavaScript 執行時可能會改變 CSSOM,同時進行會對性能產生影響

除非將 JavaScript 顯式公告為異步,否則它會阻止構建 DOM,由于默認情況下,瀏覽器遇到

最新發布的資訊信息
【系統環境|服務器應用】樹莓派安裝TensorFlow(2020-04-24 21:11)
【系統環境|服務器應用】防面試-SD_WebImage(2020-04-24 21:11)
【系統環境|服務器應用】推薦一款視頻控件xgplayer(2020-04-24 21:11)
【系統環境|服務器應用】PostgreSQL 源碼解讀(27)- 查詢語句#12(查詢優化-上拉子鏈接#2)(2020-04-24 21:11)
【系統環境|服務器應用】如何輕松學習JavaScript?(2020-04-24 21:10)
【系統環境|服務器應用】【源碼剖析】Launcher 8.0 源碼 (12) --- Launcher 啟動流程 第五步之計算桌面各布局細節參數(2020-04-24 21:10)
【系統環境|服務器應用】前臺碰撞室之console.log與文本字符(2020-04-24 21:10)
【系統環境|服務器應用】好用的Middleware實現(2020-04-24 21:10)
【系統環境|服務器應用】前臺面試每日 3+1 —— 第373天(2020-04-24 21:10)
【系統環境|服務器應用】紹圣--kafka之生產者(五)(2020-04-24 21:10)