當咱們在瀏覽器輸入一個域名後,背後究竟發生了什麼?html
第一步:當咱們輸入域名後,在 DNS 服務器進行域名查詢。前端
第二步:獲得對應的 ip 地址。linux
第三步:瀏覽器根據 ip 向 web 服務器進行通訊發送請求,而通訊的協議就是 HTTP。webpack
第四步:web 服務器回傳頁面內容。web
第五步:瀏覽器收到回傳信息的報文數據,進行渲染出咱們看得懂的頁面。算法
舉個例子:若是咱們想給張三打電話,咱們須要在通信錄中先找到名字爲張三的人,而張三這個名字就是域名,對應的手機號就是 ip。在通話過程當中我講普通話,而張三講英語,這樣確定是沒有辦法溝通的,而共同語言就是 HTTP 協議。編程
那什麼是 HTTP?json
通訊協議
,它容許將超文本標記語言(HTML)文檔從 Web 服務器傳送到客戶端的瀏覽器。應用層的面向對象的協議
,因爲其便捷、快速的方式,適用於分佈式超媒體信息系統。它於 1990 年提出,通過幾年的使用與發展,獲得不斷的完善和擴展。WEB 和 HTTPwindows
圖形信息系統
。網絡服務
,爲瀏覽者在 Internet 上查找和瀏覽信息提供了圖形化的、易於訪問的直觀界面,其中的文檔及超級連接將 Internet 上的信息節點組織成一個互爲關聯的網狀結構。
萬維網的創始人叫蒂姆·伯納斯·李(Tim Berners-Lee)簡單點說,是當代互聯網的創始人。後端
在 1990 年,他發表了一篇論文,提出了在互聯網上構建超連接文檔系統的構想,在這篇論文裏他確立了三項關鍵技術:
這三項技術直接奠基了咱們當今 Web 世界的技術,蒂姆把它稱爲萬維網(World Wide Web)。
因此,1991 年,HTTP 0.9 誕生了。
HTTP 0.9
該版本極其簡單,只有一個命令 GET。協議規定,服務器只能迴應 HTML 格式的字符串,不能迴應別的格式。服務器發送完畢,就關閉 TCP 鏈接。
雖然這一版 HTTP 協議雖然很簡單,可是做爲一個原型,充分驗證了 Web 服務的可行性。
HTTP 1.0
主要增長了如下幾部份內容:
可是 HTTP/1.0 並非一個標準,只是記錄已有實踐和模式的一份參考文檔,不具備實際的約束力,至關於一個備忘錄。
HTTP 1.1
主要增長了如下幾部份內容:
因爲 HTTP/1.1 太過龐大和複雜,所以在 2014 年又進行了一次修訂,拆分爲六份較小的文檔
這六份文檔增長了兩個大的需求:
讓 HTTP 能夠支持更多的應用,目前已經支持四種網絡協議:
HTTP 2.0
HTTP/1.1 存在兩個問題:
性能差,HTTP/1.1 是以文本的方式,藉助 CPU 的 zip 壓縮方式減小網絡帶寬,可是耗費了 前端和後端的 CPU
2010 年,Google 推出了新的 SPDY 協議,並應用於自家的服務器,HTTP/2 就是以 SPDY 爲基礎的,它的特色主要是:
HTTP 3.0
HTTP 2.0 的主要問題有隊頭阻塞問題,也就是說,若干個 HTTP 請求在複用一個 TCP 的鏈接,那麼一旦發生丟包,形成的問題就是全部的請求都必須等待這個丟了的包重傳回來,哪怕這個包不是個人 HTTP 請求的。
基於此,Google 發明了 QUIC(Quick UDP Internet Connections)協議,它是基於 UDP 的。
所以,它就解決了如下幾個問題:
HTTP 協議是構建在TCP/IP
協議之上的,是 TCP/IP 協議的一個子集。
TCP/IP 協議族
TCP/IP 協議實際上是一系列與互聯網相關聯的協議集合起來的總稱。
TCP/IP 協議族是由一個四層協議組成的系統,這四層分別爲:應用層
、傳輸層
、網絡層
、數據鏈路層
。
應用層
應用層通常是咱們編寫的應用程序,決定了向用戶提供的應用服務。應用層能夠經過系統調用與傳輸層進行通訊。如:FTP
、DNS
、HTTP
等。
傳輸層
傳輸層經過系統調用嚮應用層提供處於網絡鏈接中的兩臺計算機之間的數據傳輸功能。
在傳輸層有兩個性質不一樣的協議:TCP
、UDP
。
網絡層
網絡層用來處理在網絡上流動的數據包,數據包是網絡傳輸的最小數據單位。該層規定了經過怎樣的路徑(傳輸路線)到達對方的計算機,並把數據包傳輸給對方。
鏈路層
鏈路層用來處理鏈接網絡的硬件部分,包括控制操做系統、硬件設備驅動、NIC(Network Interface Card,網絡適配器)以及光纖等物理可見部分。硬件上的範疇均在鏈路層的做用範圍以內。
HTTP 數據傳輸過程
發送端發送數據時,數據會從上層傳輸到下層,且每通過一層都會被加上該層的頭部信息。
而接收端接受數據時候,數據會從下層傳輸到上層,傳輸前會把下層的頭部信息刪除。
傳輸層 —— TCP 三次握手
第一次握手
:客戶端發送帶有 SYN 標誌的鏈接請求報文段,而後進入 SYN_SEND 狀態,等待服務端確認。第二次握手
:服務端接受到客戶端的 SYN 報文段後,須要發送 ACK 信息對這個 SYN 報文段進行確認。同時,還要發送本身的 SYN 請求信息。服務端會將上述信息放到一個報文段(SYN+ACK 報文段)中,一併發送給客戶端,此時服務端進入 SYN_RECV 狀態。第三次握手
:客戶端接收到服務端的 SYN+ACK 報文段後,會向服務端發送 ACK 確認報文段,這個報文段發送完畢後,客戶端和服務端都進入 ESTABLEISHED 狀態,完成 TCP 三次握手。
順便說一下四次揮手:
當被動方收到主動方的FIN報文通知時,它僅僅表示主動方沒有數據再發送給被動方了。但未必被動方全部的數據都完整的發送給了主動方,因此被動方不會立刻關閉SOCKET,它可能還須要發送一些數據給主動方後,再發送FIN報文給主動方,告訴主動方贊成關閉鏈接,因此這裏的ACK報文和FIN報文多數狀況下都是分開發送的。
原理:
已經介紹了與 HTTP 協議有着密切關係的 TCP/IP 協議,接下來介紹的 DNS 服務也是與 HTTP 協議有着密不可分的關係。
一般咱們訪問一個網站,使用的是主機名或者域名來進行訪問的。由於相對於 IP 地址(一組純數字),域名更容易讓人記住。但 TCP/IP 協議使用的是 IP 地址進行訪問的,因此必須有個機制或服務把域名轉換爲 IP 地址,DNS 服務就是用來解決這個問題的,DNS提供了域名到IP地址之間的解析服務。
DNS 域名解析流程
瀏覽器緩存
:當用戶經過瀏覽器訪問某域名時,瀏覽器首先會在本身的緩存中查找是否有該域名對應的 IP 地址(若曾經訪問過該域名且沒有清空緩存)。系統緩存
:當瀏覽器緩存中無域名對應 IP 則會自動檢查用戶計算機系統 Hosts 文件 DNS 緩存是否有該域名對應 IP。路由器緩存
:當瀏覽器及系統緩存中均無域名對應 IP 則進入路由器緩存中檢查,以上三步均爲客戶端的 DNS 緩存。ISP(互聯網服務提供商)DNS緩存
: 當在用戶客服端查找不到域名對應 IP 地址,則將進入 ISP DNS 緩存中進行查詢。好比用的是電信的網絡,則會進入電信的 DNS 緩存服務器中進行查找。根域名服務器
:當以上均未完成,則進入根服務器進行查詢。全球僅有 13 臺根域名服務器,1 個主根域名服務器,其他 12 爲輔根域名服務器。根域名收到請求後會查看區域文件記錄,若無則將其管轄範圍內頂級域名(如.com)服務器 IP 告訴本地 DNS 服務器。頂級域名服務器
:頂級域名服務器收到請求後查看區域文件記錄,若無則將其管轄範圍內主域名服務器的 IP 地址告訴本地 DNS 服務器。主域名服務器
:主域名服務器接受到請求後查詢本身的緩存,若是沒有則進入下一級域名服務器進行查找,並重復該步驟直至找到正確記錄。保存結果至緩存
:本地域名服務器把返回的結果保存到緩存,以備下一次使用,同時將該結果反饋給客戶端,客戶端經過這個 IP 地址與 web 服務器創建連接。當客戶端訪問 Web 站點時,首先會經過 DNS 服務查詢到域名的 IP 地址。而後瀏覽器生成 HTTP 請求並經過 TCP/IP 協議發送給 Web 服務器。Web 服務器接收到請求後會根據請求生成響應內容,並經過 TCP/IP 協議返回給客戶端。
支持客戶/服務器模式
簡單快速
GET
、HEAD
、POST
。每種方法規定了客戶與服務器聯繫的類型不一樣。靈活
無鏈接
無狀態
問題:咱們輸入在瀏覽器裏的 Web 地址應該叫 URL 仍是 URI?
URI
:一個緊湊的字符串用來表示抽象或物理資源。
URL
:是 URI 的子集,除了肯定一個資源,還提供了一種定位該資源的主要訪問機制。
維基百科:
舉例:
http://www.ietf.org/rfc/rfc/2396.txt
: 是 URLtelnet://192.0.2.16:80
: 是 URI
HTTP 的報文頭大致能夠分爲四類,分別是:
在 HTTP/1.1 中規範了 47 種報文頭字段。
通用報文頭
請求報文頭
響應報文頭
實體報文頭
ACCEPT
做用: 瀏覽器端能夠接受的媒體類型。
Accept:text/html 表明瀏覽器能夠接受服務器回發的類型爲 text/html,也就是咱們所說的 html 文檔,若是服務器沒法返回 text/html 類型的數據,服務器應該返回一個 406 錯誤(Non Acceptable)。
ACCEPT-Encoding
做用:瀏覽器聲明本身接受的編碼方法,一般是指定壓縮方法,是否支持壓縮,只是什麼壓縮方法(gzip,deflate)。
ACCEPT-Language
做用:瀏覽器聲明本身接受的語言
Accept-Language:zh-cn,zh;q=0.7.en-us,en;q=0.3
客戶端在服務器有中文版資源的狀況下,會請求其返回中文版的響應,沒有中文版時,則請求返回英文版響應。
Connection
Connection:keep-alive 當一個網頁打開完成後,客戶端和服務器之間用於傳輸 HTTP 數據的 TCP 鏈接不會關閉,若是客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經創建的鏈接。
Connection:close 表明一個 Request 完成後,客戶端和服務器之間用於傳輸 HTTP 數據的 TCP 鏈接會關閉,當客戶端再次發送 Request,須要從新創建 TCP 鏈接。
Host
做用:請求報文頭域主要用於指定被請求資源的 Internet 主機和端口號,它一般從 HTTP URL 中提取出來的。好比:https://www.baidu.com:8080
Referer
當瀏覽器向 Web 服務器發送請求時候,通常會帶上 Referer,告訴服務器我是從那個頁面連接過來的,服務器藉此能夠得到一些信息用於處理。
User-Agent
做用:告訴 HTTP 服務器,客戶端使用的操做系統和瀏覽器的名稱和版本。
Content-Type
做用:說明了報文體內對象的媒體類型。
HTTP/1.1 經常使用方法:
GET
http://localhost/login?name=admin&password=123456
,從這段 URL 中,很容易就能夠辨認出表單提交的內容。POST
PUT
HEAD
DELETE
OPTIONS
TRACE
CONNECT
狀態碼是用以表示網頁服務器超文本傳輸協議響應狀態的 3 位數字代碼。
經常使用的 HTTP 狀態碼
狀態碼 | 狀態碼英文名稱 | 描述 |
---|---|---|
200 | OK | 請求已成功,請求所但願的響應頭或數據體將隨此響應返回 |
202 | Accepted | 已接收,已經接受請求,但未處理完成 |
206 | Partial Content | 部份內容,服務器成功處理了部分 GET 請求 |
301 | Moved Parmanently | 永久移動,請求的資源已被永久移動到新的 URI,返回信息會包括新的 URI |
302 | Found | 臨時移動,與 301 類似。但資源只是臨時被移動。客戶端應繼續使用原有 URI |
400 | Bad Request | 客戶端請求的語法錯誤,服務器沒法理解 |
401 | Unauthorized | 請求要求用戶的身份認證 |
403 | Forbidden | 服務器理解請求客戶端的請求,但拒絕執行此請求 |
404 | Not Found | 服務器沒法根據客戶端的請求找到對應資源(網頁) |
500 | Internal Server Error | 服務器內部錯誤,沒法完成請求 |
502 | Bad Gateway | 充當網關或代理的服務器,從遠端服務器接受到了一個無效的請求 |
Cookie 其實是一小段的文本信息。客戶端請求服務器,若是服務器須要記錄該用戶狀態,就向客戶端瀏覽器發送一個 Cookie。
客戶端瀏覽器會把 Cookie 保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該 Cookie 一同提交給服務器。服務器檢查該 Cookie,以此來辨認用戶狀態。
Cookie 工做原理
Session 是另外一種記錄客戶狀態的機制,保存在服務器上。客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上。
客戶端瀏覽器再次訪問只須要從該 Session 中查找該客戶的狀態就能夠了。
Session 的工做原理
保存 Session ID 的方式
Session 的有效期
每套編碼規範都有本身使用的場景,字庫表存儲了編碼規範中可以全部可以表示的字(好比:全部的漢字都在 gbk 編碼規範的字庫表裏),在一個組庫表,每個字都有對應的二進制數,這些二進制數存儲在字符集中。字庫表和字符集一一對應,相互轉換。
不一樣編碼規範節省的空間也不同,一個較短的二進制數經過一種編碼方式轉化成字符集中對應的地址,而後在字庫表中找到一個字符,顯示給用戶。
常見的編碼規範有:
ASCII 碼:
做用: 英語及西歐語言。位數: ASCII 是用 7 位表示的,能表示 128 個 字符;其擴展使用 8 位表示,表示 256 個字符。
範圍: ASCII 從 00 到 7F,擴展從 00 到 FF。
一個英文字母(不分大小寫)佔一個字節的空間,一箇中文漢字佔兩個字節的空間。
GBK 編碼標準:
兼容 GB23十二、GB13000-一、BIG5 編碼中的全部漢字,使用雙字節編碼。編碼空間爲 0x8140 ~ 0xFEFE,共有 23940 個碼位。
其中 GBK1 區和 GBK2 區也是 GB2312 的編碼範圍。收錄了 21003 個漢字。
iso8859-1
屬於單字節編碼,最多能表示的字符範圍是 0-255,應用於英文系列。好比,字母’a’的編碼爲 0x61=97。 iso8859-1 編碼表示的字符範圍很窄,沒法表示中文字符。
因爲是單字節編碼,和計算機最基礎的表示單位一致,因此不少時候,仍舊使用 iso8859-1 編碼來表示。
把其餘任何編碼當作 iso8859-1 來解碼的時候,都能解開,也是 MYSQL 的默認編碼。
位數:8 位。
範圍:從 00 到 FF,兼容 ASCII 字符集。 英文 一個字節,不支持中文
Unicode 編碼:
做用:亞 美 採用同一編碼字集。位數:16 位, 範圍:符號 6811 個,漢字 20902 個,韓文拼音 11172 個,造字區 6400 個,保留 20249 個,共計 65534 個。
英文 中文都佔用兩個字節,中英各自標點符號也是如此。
常見認證方式
什麼是 BASIC 認證?
Basic 認證是一種較爲簡單的 HTTP 認證方式,客戶端經過明文(Base64 編碼格式)傳輸用戶名和密碼到服務端進行認證,一般須要配合 HTTPS 來保證信息傳輸的安全。
BASIC 認證流程:
缺點:
什麼是 DIGEST 認證?
爲彌補 BASIC 認證存在的缺點,從 HTTP /1.1 就有了 DIGEST 認證。
DIGEST 認證一樣適用質詢/響應的方式,但不會像 BASIC 認證那樣直接放鬆明文密碼。
DIGEST 認證流程:
什麼是 SSL 客戶端認證?
SSL 客戶端認證是藉由 HTTPS 的客戶端證書完成認證的方式。憑藉客戶端證書認證,服務器可確認訪問是否來本身登陸的客戶端。
基於表單的認證方法並非在 HTTP 協議中定義的。
使用由 Web 應用程序各自實現基於表單的認證方式。
經過 Cookie 和 Session 的方式來保持用戶的狀態。
什麼是長鏈接?
長鏈接意味着進行一次數據傳輸後,不關閉鏈接,長期保持連通狀態。若是兩個應用程序之間有新的數據須要傳輸,則直接複用這個鏈接,無需再創建一個新的鏈接。就像下圖這樣。
它的優點是在屢次通訊中能夠省去鏈接創建和關閉鏈接的開銷,而且從整體上來看,進行屢次數據傳輸的總耗時更少。缺點是須要花費額外的精力來保持這個鏈接一直是可用的,由於網絡抖動、服務器故障等都會致使這個鏈接不可用,甚至是因爲防火牆的緣由。因此,通常咱們會經過下面這幾種方式來作「保活」工做,確保鏈接在被使用的時候是可用狀態:
提早多說一句,若是在作了高可用的分佈式系統場景中運用長鏈接會更麻煩一些。由於高可用必然包含自動故障轉移、故障隔離等機制。這偏偏致使了一旦發生故障,客戶端須要及時發現哪些鏈接已處於不可用狀態,並進行相應的重連,包括從新作負載均衡等工做。
什麼是短鏈接?
它的優點是因爲每次使用的鏈接都是新建的,因此基本上只要可以創建鏈接,數據就大機率能送達到對方。而且哪怕此次傳輸出現異常也不用擔憂影響後續新的數據傳輸,由於屆時又是一個新的鏈接。缺點是每一個鏈接都須要通過三次握手和四次握手的過程,耗時大大增長。
另外,短鏈接還有一個致命的缺點。當你在基於 socket 進行開發的時候,這些包含的具體資源主要就是這 5 個:源 IP、源端口、目的 IP、目的端口、協議,有個專業的叫法稱之爲「五元組」。在一臺計算機上只要這五元組的值不重複,那麼鏈接就能夠被創建。然而一臺計算機最多隻能開啓 65535 個端口,若是如今兩個進程之間須要通訊,做爲服務端的 IP 和端口必然是固定的,所以單個客戶端理論上最多隻能與服務端同時創建 65535 個 socket 鏈接。若是除去操做系統和其它進程所佔用的端口,實際還會更少。因此,一旦使用不當,在很短的時間內創建了大量鏈接,端口很容易被佔用完。這不但會致使自身沒法正常工做,還會影響到同一臺計算機上的其它進程。
代理又當服務器又當客戶端
代理的做用
能夠看到,代理是相同協議的端點,而網關是使用不一樣協議的端點。
WEB 網關
常見的網關類型
請求流入原始服務器時,服務器端 Web 網關會將客戶端 HTTP 請求轉換爲其餘協議與服務器進行鏈接,完成獲取資源之後,會將對象放在一條 http 響應中發送給客戶端
一個組織能夠經過網關對全部的輸入 Web 請求加密,以提供額外的隱私和安全性保護。客戶端能夠用普通的 HTTP 瀏覽 Web 內容,但網關會自動加密。
將 HTTPS/HTTP 網關做爲安全加速器使用的狀況愈來愈多了,這些 HTTPS/HTTP 網關位於 Web 服務器以前,一般做爲不可見的攔截網關或反向代理使用。它們接收安全的 HTTPS 流量,對安全流量進行解密,並向 Web 服務器發送普通的 HTTP 請求。這些網關中一般都包含專用的解密硬件,以比原始服務器有效的多的方式來解密安全流量,以減輕原始服務器的負荷。這些網關在網關和原始服務器之間發送的是未加密的流量。因此,要謹慎使用,確保網關和原始服務器之間的網絡是安全的。
最多見的網關,應用程序服務器,會將目標服務器與網關結合在一個服務器中實現。應用程序服務器是服務器端網關,與客戶端經過 HTTP 進行通訊,並與服務器端的應用程序相連。客戶端是經過 HTTP 鏈接到應用程序服務器的。但應用程序服務器並無回送文件,而是將請求經過一個網關應用編程接口(Application Programming Interface,API)發送給運行在服務器上的應用程序。
什麼是 HTTP 緩存?
http 緩存指的是: 當客戶端向服務器請求資源時,會先抵達瀏覽器緩存,若是瀏覽器有「要請求資源」的副本,就能夠直接從瀏覽器緩存中提取而不是從原始服務器中提取這個資源。
常見的 http 緩存只能緩存 get 請求響應的資源,對於其餘類型的響應則無能爲力,因此後續說的請求緩存都是指 GET 請求。
爲何要使用 HTTP 緩存?
1.客戶端每次都要請求服務器,浪費流量。 2.服務器每次都得提供查找,下載,請求用戶基礎若是較大,服務器存在較大壓力。 3.客戶端每次請求完都要進行頁面渲染,用戶體驗較差。
因此咱們能夠將請求的文件存放起來使用,好比使用 HTTP 緩存。
Cache-Control
:請求/響應頭,緩存控制字段。
no-store
:全部內容都不緩存。no-cache
: 緩存,可是瀏覽器使用緩存前,都會請求服務器判斷緩存資源是不是最新。max-age=x(單位秒)
:請求緩存後的 X 秒內再也不發起請求。s-maxage=x(單位秒)
代理服務器請求源站緩存後的 X 秒內再也不發起請求,只對 CDN 緩存有效。public
:客戶端和代理服務器(CDN)均可以緩存。private
:只有客戶端能夠緩存。Expires
:響應頭,表明資源過時時間,由服務器返回提供,是 HTTP1.0 的屬性,在與 max-age 共存的狀況下,優先級要低。Last-Modified
:響應頭,資源最新修改時間,由服務器告訴瀏覽器。if-Modified-Since
:請求頭,資源最新修改時間,由瀏覽器告訴服務器,和 Last-Modified 是一對,他倆會進行對比。Etag
:響應頭,資源標識,由服務器告訴瀏覽器。if-None-Match
:請求頭,緩存資源標識,由瀏覽器告訴服務器(其實就是上次服務器的 Etag),和 Etag 是一對,它兩個會進行對比。讓服務器與瀏覽器約定一個文件過時時間——Expires(GMT 時間格式)。
第一次請求的仍是:假設咱們返回一個 js 文件,而後再返回個Expires 時間。
後續請求的時候:
瀏覽器會先對比當前時間是否已經大於 Expires,也就是判斷文件是否超過了約定的過時時間。
時間沒過,不發起請求,直接使用本地緩存。
時間過時,發起請求,繼續第一次請求的邏輯。
問題:假設 Expires 已過時,瀏覽器再次請求服務器,但 js 文件相比上次並未作任何改變,那此次請求咱們是否經過某種方式加以免?
好比約定時間是一個星期,約定時間到了我還沒改。
解決:讓服務器與瀏覽器在約定文件過時時間的基礎上,再加一個文件最新修改時間的對比——Last-Modified 與 if-Modified-Since
第一次請求:假設咱們返回一個 js 文件,而後再返回個Expires 時間,再返回一個Last-Modified。
後續請求:Expires 過時,服務器帶上了文件最新修改時間 if-Modified-Since(也就是上次請求服務器返回的 Last-Modified),服務器將 if-Modified-Since 與 Last-Modified 作了個對比。
if-Modified-Since 與 Last-Modified 不相等,服務器查找了最新的 js,同時再次返回 Expires 與全新的 Last-Modified。
if-Modified-Since 與 Last-Modified 相等,服務器返回了狀態碼 304,文件沒修改過,仍是使用本地緩存。
問題:瀏覽器端能夠隨意修改 Expires,Expires 不穩定,Last-Modified 只能精確到秒,假設文件是在 1s 內發生變更,Last-Modified 沒法感知到變化,這種狀況下瀏覽器永遠拿不到最新的文件。
解決:讓服務器與瀏覽器在過時時間 Expires+Last-Modified 的基礎上,再增長一個文件內容惟一對比標記——Etag 與 If-None-Match。咱們說 Expires 有可能被篡改,這裏咱們再加入一個 max-age 來加以代替(cache-control 其中一個值)。
第一次請求:假設咱們返回一個 js 文件,而後再返回個max-age=60,再返回一個Last-Modified,還有一個文件內容惟一標識 Etag。
後續請求:60S 內,不發起請求,直接使用本地緩存。(max-age=60 表明請求成功緩存後的 60S 內再也不發起請求,與 Expires 類似,同時存在 max-age 優先級要比 Expires 高)
60S 後,瀏覽器帶上了if-Modified-Since 與 If-None-Match(上次服務器返回來的 Etag)發起請求,服務器對比 If-None-Match 與 Etag(不對比 if-Modified-Since 與 Last-Modified 了,Etag 優先級比 Last-Modified 高。)
If-None-Match 與 Etag 不相等,說明 js 內容被修改過,服務器返回最新 js 與全新的 Etag 與 max-age=60 與 Last-Modified 與 Expires
If-None-Match 與 Etag 相等,說明 js 文件內容無任何改變,返回 304,告訴瀏覽器繼續使用以前的本地緩存。
問題:咱們已經能夠精確的對比服務器文件與本地緩存文件差別,但其實上面方案的演變都存在一個較大缺陷, max-age 或 Expires 不過時,瀏覽器沒法主動感知服務器文件變化。
經過不緩存 html,爲靜態文件添加 MD5 或者 hash 標識,解決瀏覽器沒法跳過緩存過時時間主動感知文件變化的問題。
以前的瀏覽器與服務器之間的緩存都是創建在每次請求的文件都是在相同的目錄以及相同的文件名,若是目錄或者是文件名發生改變的時候就會從新請求,管那些什麼失效時間亂七八糟的花裏胡哨的東西,因此這個時候就出現了新的解決辦法。 就是經過 webpack 來解決,每次打包的時候生成新的文件。
CDN 是構建在網絡之上的內容分發網絡,依靠部署在各地的邊緣服務器,經過中心平臺的負載均衡、內容分發、調度等功能模塊,使得用戶就近獲取所需內容,減低網絡擁堵,提升用戶訪問速度和命中率。
假設多年前咱們所在的城市只有一個火車站,每次春運,整個城市的人都得去這個火車站買票,人流量以及購票的需求可想而知有多大,爲了緩解這個問題,城市的不一樣區,都出現了火車票代售點,這樣每一個區的人均可以就近買票了,火車站總站的壓力就這樣大大減輕了。
咱們能夠把每一個區的售票點稱之爲 CDN 節點,也就是前面所說的代理服務器。簡而言之,咱們能夠把CDN 理解成瀏覽器與服務器之間的臨時站點,它會替服務器處理一部分的瀏覽器請求,從而整理減輕總服務器的壓力。
咱們能夠把 CDN 的價值概括爲:
舉例:
CDN 邊緣節點緩存數據,當瀏覽器請求,CDN 將代替源站判斷並處理此處請求。
第一次請求:服務器將文件交給 CDN,CDN 來進行緩存,同時 CDN 將文件返回給瀏覽器,瀏覽器自己也進行緩存。
後續請求:
狀況 1:CDN 節點本身緩存的文件未過時,因而返回了 304 給瀏覽器,打回了此次請求。
狀況 2:CDN 節點發現本身緩存的文件過時了,爲了保險起見,本身發起請求給了服務器(源站),成功拿回了最新數據,而後再交給與了瀏覽器。
其實說到這,CDN 緩存的問題也跟前面的 http 緩存同樣,CDN 緩存時間不過時,瀏覽器始終被攔截,沒法拿到最新的文件。
可是咱們迴歸 http 緩存問題本質,緩存自己針對於更新頻率不高的靜態文件,其次,CDN 緩存提供了分流以及訪問加速其它優點條件。
CDN 相似一個平臺,是能夠經過登陸,手動更新 CDN 緩存的,變相解決了瀏覽器緩存沒法手動控制的問題。
指客戶端和服務器端就響應的資源內容進行交涉,而後提供給客戶端最爲適合的資源。內容協商會以響應資源的語言,字符集,編碼方式等做爲判斷的基準。
當瀏覽器的默認語言爲英文或者中文,訪問相同 URI 的 Web 頁面時候,就返回對應的英文或中文的 Web 頁面,這種機制稱爲內容協商(Content Negotiation)。
客戶端發起請求,服務器發送可選項列表,客戶端做出選擇後在發送第二次請求。
優勢:比較容易實現。
缺點:增長了時延,至少要發送兩次請求,第一次請求獲取資源列表,第二次獲取選擇的副本。
服務器檢查客戶端的請求頭部集並決定提供哪一個版本的頁面。
優勢:比客戶端驅動的協商要快。HTTP 提供了 Q 機制(理解爲權重),容許服務器近似匹配,還提供了 vary 首部供服務器告知下游的設備(如代理服務器)如何對請求估值。
缺點:首部集不匹配,服務器要作猜想。
某個中間設備(一般是緩存代理)表明客戶端進行協商。
優勢:免除了 web 服務器的協商開銷,比客戶端驅動的協商要快。
缺點:HTTP 並無提供相應的規範。
內容協商首部集是由客戶端發送給服務器用於交換偏好信息的,以便服務器能夠從文檔的不一樣版本中選擇出最符合客戶端偏好的那個來提供服務
服務器用下面列出的實體首部集來匹配客戶端的 Accept 首部集:
Accept 首部 | 實體首部 |
---|---|
Accept | Content-Type |
Accept-Language | Content-Language |
Accept-Charset | Content-Type |
Accept-Encoding | Content-Encoding |
假設客戶端的 Accept-Language 指定的是西班牙語,可是服務端只有英語與法語版本,這個客戶端但願在沒有西班牙語的時候優先返回英語。這就意味着,咱們須要一種 HTTP 機制更詳細的描述偏好。這種機制就是質量值(q 值)。
示例以下:
Accept-Language: en;q=0.5, fr;q=0.0, nl;q=1.0, tr;q=0.0
這個首部表示:用戶最願意接受荷蘭語(nl),英文也行(en),就是不肯意接受法語(fr)或者土耳其語(tr)。
q 值的範圍從 0.0~1.0(1.0 優先級最高)
HTTP 是客戶端瀏覽器或其餘程序與 Web 服務器之間的應用層通訊協議。在 Internet 上的 Web 服務器上存放的都是超文本信息,客戶機須要經過 HTTP 協議傳輸所要訪問的超文本信息。
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全爲目標的 HTTP 通道,簡單講是 HTTP 的安全版。
那爲何須要使用 HTTPS 來進行通訊?
咱們先看一下 HTTP 的缺點:
HTTPS 能夠認爲是HTTP
+ TLS
(安全傳輸層協議,前身是 SSL 協議)。
鑑於 HTTP 的缺點,HTTPS 在 HTTP 的基礎上增長了:
在訪問使用 HTTPS 通訊的 Web 網站時候,咱們能夠看到:
首先,須要理清的是 HTTPS 並不是是一個新的協議。HTTP 的通訊接口部分採用了 SSL 協議來實現。
能夠看出,SSL 是獨立於 HTTP 的協議,它一樣也可用於其餘協議的加密,如 SMTP 等。
對稱密鑰加密是指加密和解密使用同一個密鑰的方式,這種方式存在的最大問題就是密鑰發送問題,即如何安全地將密鑰發給對方;
爲何叫對稱加密?
一方經過密鑰將信息加密後,把密文傳給另外一方,另外一方經過這個相同的密鑰將密文解密,轉換成能夠理解的明文。
共享密鑰帶來了一個問題就是,如何可以安全地把密鑰發送給對方。而公開密鑰則較好地解決了這個問題。
非對稱的密鑰。一把是公有密鑰,一把是私有密鑰。公有密鑰是對通訊雙方公開的,任何人均可以獲取,而私有的則不公開。發送方使用這把公有密鑰對報文進行加密,接收方則使用私有的密鑰進行解密。僅僅經過密文和公有密鑰是很難破解到密文。
使用公開密鑰帶來安全的同時,也隱藏着一些問題,就是如何保證公開的這把公有密鑰的真實性?這個問題伴隨也是證書機構。經過證書來保證公有密鑰的真實性。
HTTPS 採用混合加密機制
因爲公有密鑰的機制相對複雜,致使其處理速度相對較慢。因而 HTTPS 利用了二者的優點,採用了混合加密的機制。咱們知道,共享(對稱)密鑰未能解決的問題是如何可以安全地把密鑰發送給對方。只要解決了這個問題就能夠進行安全地通訊。因而,HTTPS 首先是經過公有密鑰來對共享密鑰進行加密傳輸。當共享密鑰安全地傳輸給對方後,雙方則使用共享密鑰的方式來加密報文,以此來提升傳輸的效率。
HTTP 的工做過程
HTTP 由請求和響應構成,是一個標準的客戶端服務器模型(C/S)。HTTP 協議永遠都是客戶端發起請求,服務器回送響應。
HTTPS 的工做過程
https 通訊時,首先創建 ssl 層的鏈接,客戶端將 ssl 版本號和加密組件發到服務器端,服務器端收到後對 ssl 版本號和加密組件進行匹配,同時將 CA 證書及密鑰發送到客戶端。客戶端對證書進行驗證,驗證經過後使用非對稱加密對數據通訊時的密鑰進行協商。協商後獲得一致的得到一致的對稱加密密鑰。而後使用對稱加密算法進行 TCP 鏈接,後續的過程跟 http 的過程一致。三次握手,數據交換,四次揮手,通訊結束。
過程以下 :
SSL 會使通訊的效率下降
安全性上,HTTPS 是安全超文本協議,在 HTTP 基礎上有更強的安全性。簡單來講,HTTPS 是使用 TLS/SSL 加密的 HTTP 協議。
申請證書上,HTTPS 須要使用申請證書。
傳輸協議上, HTTP 是超文本傳輸協議,明文傳輸;HTTPS 是具備安全性的 TLS/SSL 加密傳輸協議。
鏈接方式與端口上,http 的鏈接簡單,是無狀態的,端口是 80; https 在 http 的基礎上使用了 ssl 協議進行加密傳輸,端口是 443。
HTTP 的一些標準會成爲 HTTP 性能上的瓶頸:
1. Ajax
和之前的同步通訊相比,因爲它只更新一部分頁面,響應中傳輸的數據量會所以而減小。但仍未解決 HTTP 協議自己存在的問題。
2. Comet
Comet 會先將響應置於掛起狀態,當服務器端有內容更新時,再返回該響應。所以服務器端一旦有更新,就能夠當即反饋給客戶端。
3. SPDY
Google 在 2010 年發佈,其開發目標旨在解決 HTTP 的性能瓶頸,縮短 Web 頁面的加載時間。SPDY 沒有徹底改寫 HTTP 協議,而是在 TCP/IP 的應用層與運輸層之間經過新加會話層的形式運做。同時考慮到安全性問題,SPDY 規定通訊中使用 SSL。
使用 SPDY 後,HTTP 協議額外得到的功能:
用 SPDY 時,Web 服務器要對應做出相應的改動;SPDY 的確是一種可有效消除 HTTP 瓶頸的技術,但不少 Web 網站存在的問題並不是僅僅是由 HTTP 瓶頸所致使。
4. WebSocket
WebSocket 是創建在 HTTP 基礎上的協議,所以鏈接的發起方還是客戶端,而一旦確立 WebSocket 通訊鏈接,不論服務器仍是客戶端,任意一方均可直接向對方發送報文。
WebScoket 協議的主要特色:
推送功能:支持服務器向客戶端推送數據的推送功能。
減小通訊量:只要創建起 WebSocket 鏈接,就但願一直保持鏈接狀態,和 HTTP 相比,不但每次鏈接時的總開銷減小,並且因爲 WebSocket 的首部信息很小,通訊量也相應減小了。
爲了實現 WebSocket 通訊,在 HTTP 鏈接創建以後,須要完成一次「握手」(Handshaking)的步驟。
5.WebDAV
WebDAV(Web-based Distributed Authoring and Versioning,基於萬維網的分佈式創做和版本控制)是一個可對 Web 服務器上的內容直接進行文件複製、編輯等操做的分佈式文件系統,它還具有文件建立者管理、文件編輯過程當中禁止其餘用戶內容覆蓋的加鎖功能,以及對文件內容修改的版本控制功能。