一站到底 ---前端基礎之網絡

網絡相關的知識是每一個前端工程師都應該具有的。不少從事前端的朋友們都沒系統學習過計算機網絡和http相關內容。在沒有創建一個總體的知識體系下,會有一種一站到底答題的感受,每一個知識點都大體知道問題的答案,但總不肯定,更不知道具體是怎麼回事。本文系統的梳理了與前端密切相關的網絡知識。(這是我本身學習的總結,整理出的筆記,分享給你們)html

本文中的代碼演示整理在《node.js的小美好》 前端

仍是老規則,在學以前,咱們先考考本身,我整理一下知識點,看看咱們須要掌握那些問題。而後咱們經過把問題知識點串起來去總結。node

必會:git

  • http報文都有哪些內容?
  • HTTP協議頭含有哪些重要的部分,HTTP狀態碼?
  • HTTP狀態碼狀態碼都有哪些?
  • 什麼是強緩存?什麼是弱緩存?
  • 瀏覽器的現緩存機制是什麼?如何設置HTTP緩存?
  • 你知道有哪些HTTP方法?POST 和 PUT 有什麼區別?
  • 如何對數據進行壓縮(ZLIB),Gzip? 壓縮的範圍是什麼,請求頭會壓縮嗎?
  • 跨域,爲何JS會對跨域作出限制?如何容許跨域?

基礎:github

  • 影響網速的緣由有哪些?網絡丟包的主要緣由是什麼?
  • 網絡體系結構的五層參考模型都是什麼?它們之間的關係是什麼?
  • 咱們常聽到報文、段(分組)、數據報、幀、和數據包,它們有什麼關係?
  • Ajax能發送http請求,它和http有什麼樣的關係?
  • HTTP1.0 到 http1.1 解決了什麼問題?
  • http2有什麼特性?
  • http1.1爲何會有隊首阻塞?
  • SSL與TLS關係?HTTPS協議如何實現?

補課與拓展:(慢慢更新)web

  • 經常使用的傳輸層協議有哪些?TCP和UDP分別有什麼特色?
  • 解釋一下TCP的三次握手和四次揮手?
  • 爲何說TCP多是網絡通訊的瓶頸?如何解決TCP隊首阻塞?
  • 谷歌新出QUIC爲何要基於UDP?
  • QUIC有哪些新特性,解決了什麼問題?

必會是和前端工做中聯繫最緊密的http協議相關的內容。可是若是沒有網絡基礎,就好像空中樓閣。沒法創建起知識體系。因此本文會把必會和基礎放到一塊兒,也就是本文的1-5章內容。ajax

補課與擴展:而深刻學習下一代QUIC就必須瞭解TCP和UDP的具體工做原理。因此這裏會給你們偷偷補課。一些經常使用的拓展內容也會放到後邊幾章。算法

本文會用node作代碼演示,相關代碼在github上。若是node基礎很差的同窗,我把本章全部的代碼整理成了一篇node的學習文檔。《node.js的小美好》 。每一小節會有一些習題,用來鞏固複習,我慢慢加。chrome

1 網絡基礎

咱們從第一題開始,當瀏覽器訪問www.jd.com時,咱們都知道瀏覽器向服務器發送了http請求,會把請求報文發送給服務器。那麼我先粗略分析一下這個過程。json

1.1 分組傳遞

瀏覽器會基於http協議產生一個http報文(消息),而後會把這個報文拆分紅不一樣的分組(包)。發送到路由上。路由先進行緩存,而後在根據路由錶轉發給下一個路由,直到到達服務器。

客戶端 ---> 路由--->路由.......----> 路由--->服務器
複製代碼

咱們爲何不直接把消息發送給服務器,爲何必定要分包呢?

首先,路由是先緩存再轉發,若是把整個報文直接發給服務器,那麼對路由內存要求會很是高。另外還有一個重要的概念就是網絡的帶寬,也是在鏈路上的傳輸速率,它是由單位時間內能夠傳輸的數據總量決定的。而不是咱們物理距離,舉個例子。

(1)基礎題 (來自《阿里技術之瞳》)

使用一輛卡車運輸n塊裝滿數據的1TB硬盤,以80km/h速度行駛1000km將數據運送到目的地,
卡車至少運送多少塊硬盤才能使傳輸速率超過1000Gbit/s?

答案:5625
解析:這個問題能夠簡化成兩種方案在相同時間內兩種方案要傳輸相同的數據量。
卡車的時間爲: 1000km ÷ 80Km = 12.5h
在相同時間內網絡傳輸的數據量爲: 12.5h * 3600s/h * 1000Gbit/s ÷ 8b/B = 5625000GB.
那麼卡車須要運輸相同的運算量,5625000GB  ÷ 1000GB  =  5625塊。
總結:帶寬:在鏈路上的傳輸速率(bit/sec 即 bps)
      bit(位)  // 1 Byte = 8 bit
複製代碼

拓展:那麼咱們如今分析一下交付時間

如今有一個5Mbits的報文,在寬帶是1Mbps,從客戶端C1 發送到 服務器h2,通過路由器A,B。忽略其餘影響。

C1---> A ----> B ---- h2

一次報文交換交付時間: 

C1---> A : 5Mbits / 1Mbps = 5s
A ---> B : 5Mbits / 1Mbps = 5s
B --->h2 : 5Mbits / 1Mbps = 5s
共15s

若是分紅5000組 , 那麼每一個包是1bits。

H1---> A : 1bits / 1Mbps = 1ms  

當第1個到達時A時須要1ms,第2個已經出發
當第2個已經到A時,第1個已經到達B
當第5000個到達A時,第4999個到底B,其他都到達。這時候用時5s
當第5000個到達h2時,就用時,5秒零2毫秒。

最後總結一下:
-  報文:M bits
-  鏈路寬帶:R bps
-  路由器數:n 
-  分組長度:L bits

-  一次報文交換交付時間   : T = (n+1) * (M / R)
-  分組交換報文交付時間:T = M / R + nL/R

複製代碼

因此能夠看出分組交換比一次報文交互性能要好。而上面所用的時間就叫做傳輸延遲

傳輸延遲是影響網速的最主要緣由,那麼還有一些影響網速的緣由咱們來看看:

  • 排隊延時:好比當第1個到包達時A時,若是它前面已經有一些其餘客戶端的包到達,那麼它就許多排隊等待。排隊所用的時間就是排隊延時。
  • 結點處理延遲:排隊到了之後,結點A會對包進行一些處理,這個處理時間叫結點處理延遲,一般是毫秒級的影響很是小。
  • 傳播延遲: A出發後,從A到B在鏈路上傳播還要通過必定物理距離,但傳輸的速度很是快,一般是0.7倍的光速,所用的時間叫傳播延遲。
  • 丟包: 若是不少客戶端同時向A結點發送數據包,A的緩存滿了之後,對接下來的數據包,會丟棄。而這正是丟包的主要緣由。

問題:如今咱們粗略瞭解了這個過程,那麼具體都經歷那些過程呢?

1.2 網絡體系結構

咱們先看來看OSI解釋的七成參考模型。

  • 分層:咱們根據不一樣的功能把網絡模型分層。
  • 協議:不一樣層之間規定了不一樣協議,每一個層遵循每一個層的網絡協議完成完成功能。
  • 接口:層與層之間會經過接口去進行交互。

因此這也符合咱們函數的模塊化,低層函數定義好接口API,你按照函數的接口文檔去調用依賴的函數,而後就等着讓它去處理。在實際的開發中,咱們就是這麼去實現的。

每一層經過本層的協議,增長控制信息,構造協議數據單元PUD。

應用層

  • 瀏覽器根據http協議,產生報文頭和主體
  • 對並報文進行編碼,加密,壓縮。
  • 將數據封裝好後,交給下一層,咱們將這一層的PUD叫 報文(message)

傳輸層

  • 在瀏覽器端會將報文分組,在服務器端會將報文重組。
  • 在每一個分組的頭,會加上本身協議信息。
  • 這些協議信息主要功能是SAP尋址,鏈接控制,流量控制,差錯控制
  • 將數據封裝好後,交給下一層,咱們將這一層的PUD叫 段(segment)

網絡層

  • 網絡層在拿個每一個段後,會根據IP協議,加上本身協議信息
  • 這些協議信息主要功能是:邏輯尋址(IP地址)路由轉發。
  • 將數據封裝好後,交給下一層,咱們將這一層的PUD叫 數據報(datagram)

鏈路層

  • 網絡層在拿個每一個段後,會根據IP協議,加上本身協議信息
  • 這些協議信息主要功能是:物理尋址(MAC地址),流量控制,差錯控制,接入控制。
  • 將數據封裝好後,交給下一層,咱們將這一層的PUD叫 幀(frame)

物理層

  • 物理層在拿個幀後,會把它轉化成 比特(bit),就是位,二進制編碼(一堆100111)
  • 而後將這些二進制,根據本身物理特性去表示,好比電信號啥的。
  • 而後就把它交給物理介質去傳輸啦

因此如今咱們知道了,每發送一個http請求,是針對應用層的請求和響應。應用層雖然來回只有一次。但它下面傳輸層,要把整個報文,分紅許多分組,再交給下一層,著名的TCP三次連接就是指的傳輸層的。因此應用層的一次請求和響應,再鏈路是可能要走許屢次。每一個包確定是確定擁有每一個層的協議,不可能只有上層沒有下層。而咱們常說的數據包,就應該是一個段(分組)通過處理成,最後變成比特在鏈路上傳輸。

你會發現咱們並無講表示層和會話層?由於

應用層傳輸層 咱們後邊都會詳細講。這裏咱們再講一下 網絡層鏈路層物理層

1.3 鏈路層與物理層

上面咱們知道,物理層會把比特在物理介質上傳輸。那麼主機可能和多臺電腦相連,那麼二進制碼怎麼會知道 這是發個那臺電腦,走那條網線呢?

咱們知道在鏈路層會加上要訪問主機的物理尋址(MAC地址),因此若是網線連多個電腦,會送到每臺電腦,在物理層轉化回幀,發現若是不是目標電腦的Mac地址,就不去處理。直到找到目標Mac地址的電腦。這裏用到的就是MAC協議。

1.4 網絡層與鏈路層

那麼鏈路層是怎麼知道目標機器的Mac地址的呢?

在網絡層,咱們知道了要訪問服務器的IP,首先操做系統會判斷是否是本地IP,若是不是,會發送給網關。 操做系統啓動的時候,就會被 DHCP 協議配置 IP 地址,以及默認的網關的 IP 地址 192.168.1.1。 操做系統會廣播,誰是 192.168.1.1 啊?網關會回答它,我就是,這是Mac地址。這樣咱們就知道了Mac 地址。這個廣播獲得Mac 地址的協議就是ARP協議。

網關每每是一個路由器,知道到某個 IP 地址應該怎麼走,這個叫做路由表。這樣它再從幀中取出數據報,看到了你想去的IP,它就會告訴你那你應該走那條路,並去找哪一個路由。而後在鏈路層封裝的幀中寫入那個路由的Mac地址。

路由是怎麼知道怎麼走的呢,由於路由和路由也會溝通。溝通的協議稱爲路由協議,經常使用的有OSPF和BGP。

(測試題1)不定選項 七層網絡協議(來自京東2018秋招筆試題)

用瀏覽器訪問www.jd.com時,可能使用到的協議有?
A MAC
B HTTP
C SMTP
D ARP
E RTSP

答案:A B D
解析:因此在第一題中 HTTP是在應用層用的協議 。
     MAC和ARP是在數據鏈路層用和網絡層用到的協議。
     而一樣的應用層協議SMTP是郵件傳輸協議,RTSP是實時流傳輸協議。
     在訪問www.jd.com的時候,咱們用不到。
複製代碼

2 應用層

2.1 應用層協議

應用層是基於傳輸層協議之上。常見的傳輸層協議有TCP,UDP。

  • 基於TCP:HTTP(超文本傳輸協議),FTP(文件傳輸協議),SMTP(郵件傳輸協議)
  • 基於UDP:DNS(域名系統)和最近興起的QUIC(谷歌制定低時延的互聯網傳輸層協議)

應用層的功能是完成客戶端和服務器消息交換。要想完成信息交換就必須知道資源的位置,那咱們是怎麼約定資源位置的呢。

2.2 URL:統一資源定位符

語法爲:

協議://用戶名:密碼@子域名.域名.頂級域名:端口號/目錄/文件名.文件後綴?參數=值#標誌

http://username:password@host:80/directory/file.html?query#ref
ftp://username:password@host:21/directory/file.html
news://news.newsgroup.com.hk
複製代碼

注意:

若是參數裏邊有!,%,&,/,?,=,等非西歐字符 須要encode 方法對url的進行預處理

  • decode解碼成普通字符串
  • encode普通字符串編碼,編碼後的名字很是長叫(application/x-www-form-urlencoded MIME 字符串)

2.3 代碼演示

應用層的功能是完成客戶端和服務器消息交換。

  • 瀏覽器發送http請求:會輸入ip服務和端口
  • 服務器監聽端口號,在收到請求時做出響應的

代碼演示 node建立TCP服務器

這時咱們會過頭來看,瀏覽器左下角,是否是一直在顯示等待響應,是由於咱們尚未返回數據啊,那咱們給 它返回一些數據。

這裏咱們先不用管TCP的細節部分,咱們會在傳輸層部分去講。

問題:在大體瞭解了應用層協議後,就讓咱們去具體學習http協議吧

3 HTTP協議:

這一節的內容,但是前端的看家本領,你們必定要對應着代碼本身敲出來,看看效果

  • HTTP是超文本傳輸協議,從www瀏覽器傳輸到本地瀏覽器的 一種傳輸協議,
  • HTTP協議是由從客戶機到服務器的請求(Request)和從服務器 到客戶機的響應(response)進行約束和規範。

3.1 HTTP報文

HTTP報文:用於HTTP協議交互的信息被稱爲HTTP報文。

  • 請求(Request)端的報文叫請求報文
  • 響應(response)端的報文叫響應報文

咱們那上一節以響應報文爲例,咱們以前說要符合http協議的規則,那麼http規則是什麼呢?

let responseDataTpl = `HTTP/1.1 200 OK
Connection:keep-alive
Date: ${new Date()}
Content-Length: 12
Content-Type: text/plain

Hello world!
`;
複製代碼
  • 報文首部和報文主體中間要有空行(CR+LF:回車+換行)
  • 報文首部:處理請求和響應提供的信息(上文中設置的各類信息)
  • 報文主體:所須要的資源都在(好比返回的文本信息就是Hello world)

報文首部:根據實際用途會分爲四種

  • 通用首部字段(General):請求報文和響應報文都會使用的字段
  • 請求首部字段(Requse Header):請求報文使用的首部
  • 響應首部字段(Response Header):響應報文使用的首部
  • 實體首部字段(Entity Header):與實體有關信息的字段

因此在chrome的network中,header會顯示爲:

  • General
  • Response Headers
  • Requse Headers

實體首部字段會寫進請求頭和響應頭 對於get請求後邊的參數會顯示在Query String Parameters

在上邊TCP服務器中,咱們發現每次寫符合http協議格式的響應報文很是麻煩,爲何咱們不封裝好呢?對啊,因此下面的案例咱們就用了封裝好的HTTP模塊。

代碼演示:用node搭建HTTP服務器

咱們在代碼中看到'Content-Type',它的做用是規定內容的格式。

問題:如今你把實戰中的狀態碼改爲400,發現頁面仍然能正常訪問。這其實就是你和後端按照標準預約的啊,那麼是有什麼樣子的標準呢?

3.2 HTTP狀態碼

HTTP狀態碼:是客戶端向服務端發送請求,描述請求的狀態。 狀態碼組成:以3位數字和緣由短語組成 好比(200 OK 和 206 Partial Content)

第一位數字表明類別:

-  1XX :  信息性狀態碼(接收請求正在處理)
-  2XX :  成功狀態碼(請求正常處理完畢)
-  3XX :  重定向狀態碼(須要進行附加操做以完成請求)
-  4XX :  客戶端錯誤狀態碼(服務器沒法處理請求)
-  5XX :  服務端錯誤狀態碼(服務器處理請求出錯)
複製代碼

因此狀態碼就是先後端通訊時對於狀態的一種約定,原則上只要遵循狀態碼類別的定義,即便改變RFC2616定義的狀態碼,或自行建立都是沒問題的。

像上面你非將200成功狀態改爲400,就比如,你把紅燈換成綠燈,老司機們都會亂了套。那如今咱們看看老司機們都經常使用的狀態碼都有哪些吧。

- 200 OK :請求被正常處理返回 200 OK,這也是咱們最多見的啦
- 204 No Content :請求處理成功可是沒有資源返回,就是報文中沒有報文主體
- 206 Partial Content :客戶端進行範圍請求,就是請求資源一部分,服務器返回請求這部分(Content-Range)

- 301 Moved Permanently:永久重定向(資源的URL已經更新)
- 302 Found :臨時重定向(資源的URI已經臨時定位到其餘位置了)
- 303 See Other: 對應的資源存在另外一URL,資源的URL已經更新,是否按新的去訪問
- 304 Not Modified:客戶端發附帶條件的請求,服務端容許請求訪問資源,但沒有知足條件
- 307 Temporary Redirect: 也是臨時重定向

- 400 Bad Request : 請求報文中存在語法錯誤
- 401 Unauthorized : 須要有HTTP認證
- 403 Forbidden : 請求訪問的資源被服務器拒絕了
- 404 Not Found : 服務器上沒有找到資源
- 500 Internal Server Error: 服務器執行請求時出錯
- 503 Service Unavailable : 服務器處於超負載,正在進行停機維護
複製代碼

代碼演示:用url路徑模塊,完成了node路由

(測試題3)單選題 http狀態碼(來自阿里技術之瞳)

chrome DevTools的Network面板中參看靜態資源加載狀況,當發現靜態資源的HTTP狀態碼
是___時,須要使用強制刷新以便得到最新版的靜態資源?
  A 204
  B 304
  C 403
  D 501

答案:B
解析:304是資源重定向,客戶端發附帶條件的請求,服務端容許請求訪問資源,但沒有知足條件
     你是否是還有點蒙呢,彆着急httpd的緩存協議裏你就會看見它啦。
複製代碼

問題:咱們知道了狀態碼錶明的含義,可是它們在什麼場景下會出現呢?讓咱們一個一個去學習吧

3.2 HTTP壓縮協議

HTTP壓縮協議理解起來很簡單,就好像你要給你朋友在QQ上傳1個1G文件,須要10分鐘,哇網速好快哦。 可是你要是壓縮一下,這個文件就變成了300M。再給你朋友傳可能就須要3分鐘。而後你壓縮須要1分鐘,他解壓須要一分鐘。這樣大家5分鐘就搞定啦。一樣的道理。

  • http請求頭帶:Accept-Encoding: gzip, deflate, br

這是瀏覽器告訴服務器我支持什麼樣的壓縮格式,優先級是什麼樣的。

  • http響應頭帶:Content-Encoding: gzip

這是服務器告訴瀏覽器我已經按什麼樣子的格式壓縮了,解壓工做你拜託你了

因此在瀏覽器上咱們就須要根據請求頭中的Accept-Encoding去判斷,瀏覽器支持什麼壓縮啊。而後壓縮以後再告訴瀏覽器,我已經給你壓縮成什麼樣子啦。

代碼演示:2.5 用gzip對文件進行壓縮

3.3 HTTP緩存協議

3.3.1 強緩存

Catche Contrl: :是通用首部字段,就是以前將的發送報文和響應報文都會使用的。能夠對文件裏引用資源的緩存進行設置

這裏舉一個簡單的例子:

瀏覽器發訪問http://localhost:10080/
  -       '請求報文沒帶 Cache-Control' 客戶端說我要訪問首頁
  
  服務器返回數據
  -       '響應報文帶:Cache-Control : max-age = 604800'  服務器說給你index.html和加載裏面資源,並告訴你這些資源一週以內不要沒必要確認了
  
  瀏覽器刷新的網頁再次訪問http://localhost:10080/時
  -        裏面的資源就不會再發送請求了,直接從緩存中拿  你會在chrome,network中看到Time是0(from memory catch)

  服務器返回數據
  -       服務器只返回index.html文件


  這時候你強制刷新瀏覽器(command+shift+R) 
  -       '請求報文帶 Catche Contrl:no-cache '客戶端說我不要緩存過的數據,我要源服務器的數據
  
 服務器返回數據
  -       服務器返回index.html文件和依賴的資源
複製代碼

這就是強緩存,所謂強是在條件內,你網頁依賴的資源都不會發送http請求了。能夠直接從網頁裏面拿。

代碼演示:瀏覽器緩存協議的實現

3.3.2 協商緩存

有兩種:

第一種:If-Modified-Since/Last-Modified

服務器會下發一個Last-Modified最後修改時間。而後瀏覽器會記住這個時間。當瀏覽器第二次請求時會帶上if-modified-since的時間。服務器能夠去比較這份文件在if-modified-since的時間後是否修改過。若是沒有修改過,那就返回304.

  • Last-Modified:標示這個響應資源的最後修改時間。web服務器在響應請求時,告訴瀏覽器資源的最後修改時間。
  • If-Modified-Since:當資源過時時(使用Cache-Control標識的max-age),發現資源具備Last-Modified聲明,則再次向web服務器請求時帶上頭 If- -Modified-Since,表示請求時間。web服務器收到請求後發現有頭If-Modified- Since 則與被請求資源的最後修改時間進行比對。若最後修改時間較新,說 明資源又被改動過,則響應整片資源內容(寫在響應消息包體內),HTTP 200;若最後修改時間較舊,說明資源無新修改,則響應HTTP 304 (無需包 體,節省瀏覽),告知瀏覽器繼續使用所保存的cache。

代碼演示:瀏覽器緩存協議的實現

上面那個代碼中咱們服務器並無實現去記錄文件修改時間,咱們只要拿一段時間內去比較。咱們知道了使用 if-modified-since,服務器就要每次記錄文件的一個修改時間。因此用時間去判斷並非很好。

第二種:Etag/ If-None-Match

服務器Etag會下發一個字符串,而後瀏覽器在第二次請求時會在if-none-match中帶上這個字符串。這時候服務器能夠比較兩個字符串,若是相同,就讓瀏覽器去緩存中去取。

  • Etag:web服務器響應請求時,告訴瀏覽器當前資源在服務器 的惟一標識(生成規則由服務器決定)
  • If-None-Match:當資源過時時(使用Cache-Control標識的max- age),發現資源具備Etage聲明,則再次向web服務器請求時帶 上頭If-None-Match (Etag的值)。web服務器收到請求後發現 有頭If-None-Match 則與被請求資源的相應校驗串進行比對,決 定返回200或304。

代碼演示:瀏覽器緩存協議的實現

那麼如今在學完兩種緩存以後,你會問,若是同時都有,那麼瀏覽器是如何判斷的呢?

3.3.3 瀏覽器緩存機制

因此能夠看出,強緩存優先於協商緩存。

(習題4)不定選項 HTTP緩存 (來自京東2018秋招筆試題)

如下哪些是HTTP請求中瀏覽器緩存機制會用到的協議頭?
A Last-Modified 
B Etag
C Referer
D Authorization

答案: A B
複製代碼

3.4 HTTP方法

post和get區別最近好像總有爭論,到底有什麼區別。既然都是應用層的協議,咱們不妨迴歸到本質就看看。咱們先來將一下http都有哪些方法,再說post和get的區別。

3.4.1 HTTP方法

  • GET:獲取資源
  • POST:傳輸實體主體
  • PUT:傳輸文件
  • HEAD:獲取報文首部
  • DELETE:刪除文件
  • OPTIONS:查詢支持方法
  • TRACK:追蹤路徑
  • CONNECT:要求用隧道協議鏈接代理

3.4.2 GET 與 POST區別

協議不久是規定應用層雙方的行爲和約定嗎?那麼咱們就分別從瀏覽器和服務器去看看。

瀏覽器:

  • GET是請求數據,使用URL或Cookie傳參。POST是傳輸實體主體因此會把參數放到報文體中
  • GET數據放到URL中,瀏覽器對URL大小有限制,因此數據大小進行限制。POST是傳輸實體主體,因此大小沒有限制
  • GET數據放到URL中,因此安全性確定不高啊,因此不能用來傳遞敏感信息。POST相對安全
  • GET是請求數據因此URL地址能夠後退,而POST發送數據不會(chrome中post就會後退)。
  • GET是請求因此會被瀏覽器主動cache,而POST是發送數據,因此不會除非手動設置。

服務器:

  • get是把參數放到URL中去處理
  • 而post是觸發了服務器中監聽的請求事件,服務器可能會作出處理,影響返回結果

這裏若是不是理解,建議先把這小節實戰代碼看一下:2.6 瀏覽器緩存協議的實現

看完服務具體是如何響應的,如今你對下面這句話是否是理解了呢?

「GET和POST最大的區別主要是GET請求是冪等性的,POST請求不是。冪等性是指一次和屢次請求某一個資源應該具備一樣的反作用。簡單來講意味着對同一URL的多個請求應該返回一樣的結果。」

答了這麼多,不知道你發現沒有。瀏覽器的全部行爲都是根據這兩個動做作出的相關反應啊。 那麼何時使用get,何時使用post?

根據協議使用啊,不都給你規定好了嗎?請求數據的時候用get,傳輸實體主體的時候用post。

問題:哈哈,學到這,你是否是漸漸明白,並找到一直學很差網絡的緣由了,都怪瀏覽器太智能!對,現代瀏覽器已經很是智能了,因此不少時候,即便的代碼質量不高,它也能給你有很好的優化。可是咱們畢竟仍是要作一名合格的前端工程師,那麼下一節就讓咱們走進瀏覽器吧

4 瀏覽器與協議

4.1 XHR 與 AJAX

對於前端工程師來講,AJAX再熟悉不過了,咱們知道它是用來發送http請求的。那麼它到底與http什麼關係?那咱們先來手寫一個AJAX。

  • AJAX全稱是Asynchronous JavaScript and XML(異步js和XML)。異步js,咱們比較容易理解。那麼什麼是XHR呢。

  • XHR全稱是XMLHttpRequest,就是XML的http的請求。其實這是一個瀏覽器層面的API。通俗點講就是瀏覽器給你封裝好了的http功能函數。

在以前的課程,咱們發送的http請求都是瀏覽器本身主動發送的。若是,瀏覽器沒有開放這麼一個功能。你就固然沒有能力主動向服務器獲取數據。因此就完不成交互。這就是爲何在AJAX 以前要經過刷新頁面來解決。

那麼咱們如何理解XHR是瀏覽器層面的API?

  • 咱們在node服務端的時候知道,咱們常常須要須要操做請求頭中的數據,好比根據請求頭中的壓縮機制作出相應的處理。但咱們在前端用ajax獲得數據的時候。並不用考慮壓縮啊,這就是由於XHR是一個瀏覽器層面的API。它向咱們隱藏了大量的底層處理,好比壓縮,緩存。換句話說,瀏覽器也沒有開放給你作這些事能力。

  • 總結一下,其實很好理解,咱們的web頁面是跑在瀏覽器上的,雖然瀏覽器是智能的,但也是通用的,不是爲咱們定製的。這也正是webapp不如原生app的體驗流暢的緣由啊。原聲app能夠理解爲(瀏覽器+頁面)。而webapp是在瀏覽器上寫內容。

可是瀏覽器單單發送http請求的是不能知足咱們平常開發需求的。爲了完成跟多的功能,咱們有長輪詢,瀏覽器也提供的了websocket的API。這寫具體涉及到業務的場景的功能。有機會單寫一篇吧。

問題:咱們知道了瀏覽器給咱們帶來不少的限制,那麼具體業務有哪些影響呢?

4.2 瀏覽器安全與跨域

因此咱們再XHR的會有不少限制,其中對咱們影響很大的就是不容許發送不一樣協議,地址和端口號的請求。

那麼咱們常見的解決方案有三種:

  • jsonp :是把請求假裝成標籤去請求。由於標籤是瀏覽器本身發送請求,因此不受同源策略影響啊
  • 代理服務器:這個也很好理解,我把全部請求都發送到不跨域的代理服務器上,服務器上但是咱們說的算,只要通過處理把數據返回給瀏覽器就好。
  • CORS:這是咱們今天主要講。由於解鈴還須繫鈴人,既然是你限制的,那麼你總得給我一個解決辦法吧。瀏覽器給出的解決辦法就是(CORS)

cors的辦法也很簡單:

  • 若是瀏覽器發現你已經跨域了它會發送一個帶原IP的請求頭Origin: http://localhost:8088
  • 問服務器,你讓不讓localhost:8088訪問你的文件啊,若是瀏覽器贊成就回復一個Access-Control-Allow-Origin: http://localhost:8088 。表示,這個IP能夠訪問的
  • 而後服務器在發起正式請求
  • 若是服務器沒有給瀏覽器返回Access-Control-Allow-Origin或不容許這個地址訪問,那麼瀏覽器就報跨域請求錯誤

固然,爲了安全起見CORS的請求都會忽略掉cookie 和 HTTP認證等用戶憑證。若是你想用,一樣在請求頭帶Origin時在發送一些參數。服務器也是在第一次返回時告訴瀏覽器贊成仍是不一樣意。

代碼演示: 2.8 node處理跨域

5 http發展

5.1 HTTP1.0 到http1.1

  • HTTP1.0的時候,每次發送一個http請求就要創建一次TCP鏈接,而後再斷開

  • http1.1的時候,引入了Connection:keep-alive的機制,鏈接後不斷開能夠繼續發送請求
  • 但每次請求都是第一個回來,第二個再出發。後來瀏覽器又引入了 pipelining的管道化鏈接。

  • 在一個TCP鏈接內,多個HTTP請求能夠並行,下一個HTTP請求在上一個HTTP請求的應答完成以前就發起 這個不須要你去設置,引入了Connection:keep-alive,瀏覽器自動會這麼處理。但這又有一個問題,因爲HTTP1.1服務端返回響應數據的順序必須跟客戶端請求時的順序一致,這樣也就是要求先進先出。因此很容易形成隊首阻塞。就是你第一個請求不返回,後面都得在那等着。

因此這節的重點就是http2就解決了隊首阻塞的問題。但http2是基於https的,那就讓咱們先學習https吧

5.2 HTTPS

HTTPS是針對HTTP安全性不足,作的改進,咱們先看看HTTP安全性都有哪些不足

  • 通訊就是明文
  • 沒有驗證通訊方身份
  • 沒法證實報文完整性

** 因此 HTTS = HTTP + 加密 + 認證 + 完整性保護 **

那麼如今咱們先看看如何加密解密的吧?

  • 好比我有一份數據要給你,我只須要把它加密了,你在解密這樣不就安全了。

  • 因此我有一個私鑰用來加密,給別人解密的是公鑰

  • 可是這個時候,咱們又不能保證別人拿到的公鑰就是個人公鑰。萬一數據沒有變,可是公鑰被劫持,解密出來的內容就也不是我想發給對方的啦

  • 因此我把公鑰交給第三方CA認證一下,第三方把公鑰變成了證書

  • 這樣瀏覽器再拿到我發給它的證書的時候,他去和第三方CA問一下,這是否是他的證書啊。

  • 第三方說是,這樣咱們就安全了。

  • 一樣瀏覽器也會以一樣的私鑰和證書的方式對傳給服務器的數據進行加密解密。在第三方認證的時候,咱們會詳細登記本身的信息。這樣咱們彼此也就完成了身份認證。

  • 最後,這個加密算法還用摘要功能來保證數據的完整性

如今咱們知道了就是經過一個私鑰和證書對數據進行進行加解密。因此HTTPS協議只是HTTP通訊接口部分用SSL協議代替而已。而剛纔咱們講的這個過程就是SSL協議的內容。它是由網景公司發明,後來轉交給IETF,IETF在SSL基礎上制定的TLS(改個名字)。

代碼演示:3.1 https的node服務器的搭建

5.2 HTTP2.0

如今終於來到咱們http2啦。還記得咱們說的http1.1的對手阻塞嘛。對http2就解決了這個問題。

  • (1)多路複用,並不在遵循先進先出。

那麼如今有一個問題,http2中,既然沒有先進先出,那麼重要的文件加載的慢,那不就尷尬啦。

  • (2)http2定義了請求優先級

咱們可讓一些重要的請求優先加載。瀏覽器也智能的根據http2定義出的優先級規則去顯示頁面。

  • (3)頭部壓縮

咱們知道咱們在用Gzip方式給報文體進行壓縮。http2給報文頭也進行了壓縮。你可別小看了報文頭,通常網頁的報文頭能佔到報文的40%。 而壓縮後能減小60%左右。

  • (4)性能上新增了二進制分幀層。也獲得了大大的提高。分針層對應的就是http報文。因此http/1.1是一個文本協議,而 http2 是一個不折不扣的二進制協議。

接下來就讓咱們動手去實踐一下吧。

最後,寫的好累。。。以爲這一篇寫不完。後邊寫的太糙了。我慢慢改改。拓展有空在寫吧。

相關文章
相關標籤/搜索