天天看點

【java總結】計算機網絡-HTTP【java總結】計算機網絡-HTTP篇

【java總結】計算機網絡-HTTP篇

本内容參考了多位大佬,幾十篇部落格整理出來的,友善自己的複習,同時有不全面,不正确的内容歡迎補充

HTTP

這個協定對于網絡工程師來說,他隻是一個協定而已,但對于我們java工程師,或者前端工程師,或者其他非網絡計算機從業者都太重要了。我們java開發的很大部分都是web應用,。我們對Web的操作都是通過HTTP協定來進⾏傳 輸資料的,前端也是很直接的利益相關(怎麼有股知乎的味道。)總而言之,Http就是Web通信的基礎,這是我們必學的。我一定要總結的全面,透徹。友善自己,友善大家。

Http基本概念

HTTP全稱是 HyperText Transfer Protocal,即:超文本傳輸協定。是網際網路上應用最為廣泛的一種網絡通信協定,它允許将超文本标記語言(HTML)文檔從Web伺服器傳送到用戶端的浏覽器。目前我們使用的是HTTP/1.1 版本。

前面不是說了網絡的分層概念嗎,我們的HTTP協定是在最上層,也就是應⽤層。這是最貼近我們的程式員的層次。

我們逐漸一點點來看,解決一個又一個小概念,争取建立一個完整的HTTP體系

最終解決一個大的問題:在浏覽器輸入 URL 後發生了什麼?

URI 和 URL 有什麼差別?

URI:統一資源辨別符(Uniform Resource Identifier),就是在某一規則下能把一個資源獨一無二地辨別出來。它可以了解成是一個資源的名字,比如

積木

,

jimu98

甚至

[email protected]

或者是

aaa.html

,隻要可以唯一的辨別一個名字,那麼我們就把他稱作uri,甚至

https://www.jimu98.cn/aaa.html

也是一個URI(這個不是應該叫URL,别着急)

URI:統一資源辨別符(uniform resource identifier),比如

https://www.jimu98.cn/aaa.html

其實,我們可以發現,URI強調的是給資源标記命名,URL強調的是給資源定位,但是你會發現,URL顯然比URI包含資訊更多,我通過URL也可以知道自己的資源名字可能是

aaa.html

,并且我還知道了他的位址.

是以大多數情況下大家覺得給一個網絡資源分别命名和給出位址太麻煩,幹脆就用位址既當位址用,又當标記名用

是以,URL也充當了WWW網際網路裡面URI的角色,但是他比URI多了一層意義,我不光知道你叫什麼,我還知道你在哪裡。

我們在浏覽器輸入的都是URL,因為我們輸入的目的是為了找到某一個資源。

DNS:負責解析域名

當我們需要通路一個遠端資源的時候,必然要和他建立連接配接(建立TCP,或者UDP連接配接,基于IP協定)

是以我們要知道他的位址,可是随着網際網路的發展,越來越多的web應用進入大家視線,比如我們通路一些常用的網站,

www.baidu.com

www.jd.com

這些時候,我們明明輸入的不是ip。

其實讓我們記IP,也是可以通路的,但是你願意記那麼長的數字嗎,反正我不願意,于是乎DNS

域名解析協定

誕生了,他就可以把一個特殊含義的域名轉換成一個IP位址。

但是你想啊,你想要用baidu這個名字,别人也想,那到底該給誰呢。于是肯定有專門的管理機構去統一規範。

但是,我們還有一個叫做本地DNS的東西,通過配置Host檔案,去自定義一個域名,實作本地映射。

DNS工作流程:

1、在浏覽器中輸入www.baidu.com 域名,作業系統會先檢查自己本地的hosts檔案是否有這個網址映射關系,如果有,就先調用這個ip位址映射,完成域名解析。

2、如果hosts裡沒有這個域名的映射,則會查找本地DNS解析器緩存,是否有這個網址映射關系,如果有,直接傳回,完成域名解析。

3、如果hosts與本地DNS解析器緩存都沒有相應的網址映射關系,首先會找TCP/IP參數中設定的首選DNS伺服器,在此我們叫它本地DNS伺服器,此伺服器收到查詢時,如果要查詢的域名,包含在本地配置區域資源中,則傳回解析記過給用戶端,完成域名解析,此解析具有權威性。

4、如果要查詢域名,不由本地DNS伺服器區域解析,但該伺服器已緩存了此網址映射關系,則調用這個IP位址映射,完成域名解析,此解析不具有權威性。

5、如果本地DNS伺服器本地區域檔案與緩存解析都失效,則根據本地DNS伺服器的設定(是否設定轉發器)進行查詢,如果未用轉發模式,本地DNS就把請求發至13台根DNS,根DNS伺服器收到請求後會判斷這個域名(.com)是誰來授權管理,并會傳回一個負責該頂級域名伺服器的一個IP。本地DNS伺服器收到IP資訊後,将會聯系負責.com域的這台伺服器。這台負責.com域的伺服器收到請求後,如果自己無法解析,它就會找一個管理.com域的下一級DNS伺服器位址(baidu.com)給本地DNS伺服器。當本地DNS伺服器收到這個位址後,就會找baidu.com域伺服器,重複上面的動作,進行查詢,直至找到www.baidu.com 主機。

6、如果用的是轉發模式,此DNS伺服器就會把請求轉發至上一級DNS伺服器,由上一級伺服器進行解析,上一級伺服器如果不能解析,或找根DNS或把請求轉至上上級,以此循環。不管是本地DNS伺服器用是轉發,還是根提示,最後都是把結果傳回給本地DNS伺服器,由此DNS伺服器再傳回給客戶機。

HTTP請求封包

http請求由三部分組成,分别是:請求行、請求報頭、空行、請求資料

可以分别了解成我使用什麼方法,我支援什麼格式,我的格式說完了,我的正式資料

【java總結】計算機網絡-HTTP【java總結】計算機網絡-HTTP篇

請求行

請求行由請求方法、URL字段和HTTP協定的版本組成,格式如下

Method Request-URI HTTP-Version CRLF

其中 Method 表示請求方法;GET、POST、HEAD、PUT、DELETE、TRACE、CONNECT、OPTIONS(可選項)

Request-URI是一個統一資源辨別符;(前面也說過了)

HTTP-Version表示請求的HTTP協定 版本;(後面說版本的差別)

CRLF表示回車和換行(除了作為結尾的CRLF外,不允許出現單獨的CR或LF字元)。

請求報頭

通用報頭:(現在在解釋請求封包,後面還有響應封包,他們兩公用的報頭)

Date:表示消息産生的日期和時間。

Connection:允許發送指定連接配接的選項。例如指定連接配接是連續的;或者指定“close”選項,通知伺服器,在響應完成後,關閉連接配接。

Cache-Control:用于指定緩存指令,緩存指令是單向的(響應中出現的緩存指令在請求中未必會出現),且是獨立的(一個消息的緩存指令不會影響另一個消息處理的緩存機制)。

//————————————————–

請求報頭:(不同的報頭在不同的http版本種誕生時間不同,可以看後面版本了解)

Host:請求的主機名,允許多個域名同處一個IP位址,即虛拟主機。

User-Agent:發送請求的浏覽器類型、作業系統等資訊。

Accept:用戶端可識别的内容類型清單,用于指定用戶端接收哪些類型的資訊。

Accept-Charset請求報頭域用于指定用戶端接受的字元集 。

Accept-Encoding:用戶端可識别的資料編碼。

Accept-Language:表示浏覽器所支援的語言類型。

Authorization請求報頭域主要用于證明用戶端有權檢視某個資源。

Connection:允許用戶端和伺服器指定與請求/響應連接配接有關的選項。例如,這時為Keep-Alive則表示 保持連接配接。

Transfer-Encoding:告知接收端為了保證封包的可靠傳輸,對封包采用了什麼編碼方式。

//————————————————–

實體報頭:(用來定義被傳送資料的類型,既可用于請求,又可用于響應)

Content-Type:發送給接收者的實體正文的媒體類型。

Content-Lenght:實體正文的長度。

Content-Language:描述資源所用的自然語言。

Content-Encoding:實體報頭被用作媒體類型的修飾符。它的值訓示了已經被應用到實體正文的附加 内容的編碼,因而要獲得Content-Type報頭域中所引用的媒體類型,必須采用相應的解碼機制。

Last-Modified:實體報頭用于訓示資源的最後修改日期和時間。

Expires:實體報頭給出響應過期的日期和時間。

空行

就是告訴伺服器,我的請求頭到此為止

請求資料

在get中,資料就在url中展現了,是以這裡的資料指的在post送出中的資料,至于PUT、DELETE這些,他們其實也可以了解成post
【java總結】計算機網絡-HTTP【java總結】計算機網絡-HTTP篇

HTTP響應封包

HTTP 的響應封包由狀态行、響應報頭、空行、響應正文 (和請求體相當類似)

狀态行

就是告訴我們 請求的資料是否找到,如果沒找到是因為啥,傳回一些狀态碼(404大家都遇到過吧)
xx:表明服務端接收了用戶端請求,用戶端繼續發送請求;
xx:用戶端發送的請求被服務端成功接收并成功進行了處理;
xx:服務端給用戶端傳回用于重定向的資訊;
xx:用戶端的請求有非法内容;
xx:服務端未能正常處理用戶端的請求而出現意外錯誤。

xx:
200 OK:表示從用戶端發送給伺服器的請求被正常處理并傳回;
204 No Content:表示用戶端發送給用戶端的請求得到了成功處理,但在傳回的響應封包中不含實體的主體部分(沒有資源可以傳回)
206 Patial Content:表示用戶端進行了範圍請求,并且伺服器成功執行了這部分的GET請求,響應封包中包含由Content-Range指定範圍的實體内容。

xx:
301 Moved Permanently:永久性重定向,表示請求的資源被配置設定了新的URL,之後應使用更改的URL;
302 Found:臨時性重定向,表示請求的資源被配置設定了新的URL,希望本次通路使用新的URL;
303 See Other:表示請求的資源被配置設定了新的URL,應使用GET方法定向擷取請求的資源
304 Not Modified:表示用戶端發送附帶條件(是指采用GET方法的請求封包中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的請求時,伺服器端允許通路資源,但是請求為滿足條件的情況下傳回改狀态碼;
307 與相同,但不會把POST請求變成GET

xx:
400 Bad Request:表示請求封包中存在文法錯誤;
401 Unauthorized:經許可,需要通過HTTP認證;
403 Forbidden:伺服器拒絕該次通路(通路權限出現問題)
404 Not Found:表示伺服器上無法找到請求的資源,除此之外,也可以在伺服器拒絕請求但不想給拒絕原因時使用;

xx:
500 Inter Server Error:表示伺服器在執行請求時發生了錯誤,也有可能是web應用存在的bug或某些臨時的錯誤時;
503 Server Unavailable:表示伺服器暫時處于超負載或正在進行停機維護,無法處理請求;
           

突然想到某個老師教過,當你遇到404錯誤,你給使用者傳回一個503,顯得你網站特别火爆(啊哈哈哈哈哈哈)

也就是說,其實看到某些狀态碼的時候,也不一定可信,因為背景可以改掉

Get與POST的差別

GET與POST是我們常用的兩種HTTP Method(就是你在前端form表單那裡寫的,或者你背景用@PostMapping接收的那個)
  • GET在浏覽器回退時是無害的,而POST會再次送出請求。
  • GET産生的URL位址可以被收藏,而POST不可以。
  • GET請求會被浏覽器主動cache,而POST不會,除非手動設定。
  • GET請求隻能進行url編碼,而POST支援多種編碼方式。
  • GET請求參數會被完整保留在浏覽器曆史記錄裡,而POST中的參數不會被保留。
  • GET請求在URL中傳送的參數是有長度限制的,而POST麼有。
  • 對參數的資料類型,GET隻接受ASCII字元,而POST沒有限制。
  • GET比POST更不安全,因為參數直接暴露在URL上,是以不能用來傳遞敏感資訊。
  • GET參數通過URL傳遞,POST放在Request body中。

但是,GET和POST的底層都是TCP/IP,你要給GET加上request body,給POST帶上url參數,技術上是完全行的通的。

但是不同的浏覽器對資料量有所限制,業界不成文的規定是,(大多數)浏覽器通常都會限制url長度在2K個位元組,而(大多數)伺服器最多處理64K大小的url。

如果你用GET服務,在request body偷偷藏了資料,不同伺服器的處理方式也是不同的,有些伺服器會幫你卸貨,讀出資料,有些伺服器直接忽略,是以,雖然GET可以帶request body,也不能保證一定能被接收到。

還有一個比較重要的差別,很多面試筆記裡面都沒有寫這一條()

對于GET方式的請求,浏覽器會把http header和data一并發送出去,伺服器響應200(傳回資料);

而對于POST,浏覽器先發送header,伺服器響應100 continue,浏覽器再發送data,伺服器響應200 ok(傳回資料)。

因為POST需要兩步,時間上消耗的要多一點,看起來GET比POST更有效。是以Yahoo團隊有推薦用GET替換POST來優化網站性能。

并不是所有浏覽器都會在POST中發送兩次包,Firefox就隻發送一次。

以上就是post和get全部差別的

【java總結】計算機網絡-HTTP【java總結】計算機網絡-HTTP篇

其實HTTP協定中還⽀持着其他的⽅法,⽐如:Input、Delete、OPTIONS很多這樣的⽅法。

⽽由于常⽤,于是我們也可能僅僅知道GET和POST⽅法了。

HTTP提供⽅法的⽬的就是為了告知伺服器該用戶端想進⾏什麼操作。當HTTP是OPTIONS⽅法的時候, 伺服器端就會傳回它⽀持什麼HTTP⽅法。 當然了,現在RESTful盛⾏,也就是充分利⽤了HTTP協定的這些⽅法

RESTful 以後再專門總結一下(不然我怎麼水部落格)

HTTP協定版本詳解

版本這裡有些枯燥,都是些知識點,作為了解可以跳過

到現在為⽌,HTTP協定已經有四個版本了:

  • HTTP/0.9

    HTTP協定的最初版本,功能簡陋,僅支援請求方式GET,并且僅能請求通路HTML格式的資源。

  • HTTP1.0

    引入了新的指令POST和HEAD(http資料頭部)指令,可自定義類型, 常見Content-Type值:text/xml image/jpeg audio/mp3

    同時也開始支援cache,就是當用戶端在規定時間内通路統一網站,直接通路cache即可。

    但是1.0版本的工作方式是每次TCP連接配接隻能發送一個請求,當伺服器響應後就會關閉這次連接配接,下一個請求需要再次建立TCP連接配接,就是不支援keepalive。

  • HTTP1.1

    新增方法:PUT、PATCH、OPTIONS、DELETE,引入了持久連接配接(persistent connection),即TCP連接配接預設不關閉,可以被多個請求複用,不用聲明Connection: keep-alive。

  • HTTP/2

    HTTP2.0是SPDY(谷歌公司研發的https的一種協定)的更新版

    1.頭資訊和資料體都是二進制,稱為頭資訊幀和資料幀

    2.複用TCP連接配接,在一個連接配接裡,用戶端和浏覽器都可以同時發送多個請求或回應,且不用按順序一一對應,避免了“隊頭堵塞“,此雙向的實時通信稱為多工(Multiplexing)

    3.引入頭資訊壓縮機制(header compression),頭資訊使用gzip或compress壓縮後再發送;用戶端和伺服器同時維護一張頭資訊表,所有字段都會存入這個表,生成一個索引号,不發送同樣字段,隻發送索引号,提高速度

    4.HTTP/2 允許伺服器未經請求,主動向用戶端發送資源,即伺服器推送(server push)

  • HTTP/3

HTTP1.0和HTTP1.1差別

HTTP1.0和HTTP1.1最主要的差別就是: HTTP1.1預設是持久化連接配接!

在HTTP1.0預設是短連接配接:簡單來說就是:每次與伺服器互動,都需要新開⼀個連接配接!

在HTTP1.1中預設就使⽤持久化連接配接來解決:建⽴⼀次連接配接,多次請求均由這個連接配接完成!(如果阻塞 了,還是會開新的TCP連接配接的)

HTTP 1.1增加host字段
HTTP 1.1中引⼊了 Chunked transfer-coding ,範圍請求,實作斷點續傳(實際上就是利⽤ HTTP消息頭使⽤分塊傳輸編碼,将實體主體分塊傳輸)

HTTP 1.1管線化(pipelining)理論,用戶端可以同時發出多個HTTP請求,⽽不⽤⼀個個等待響應之 後再請求

僅僅是提出了理論,浏覽器預設關閉HTTP pipelining!

HTTP2和HTTP1.1的差別

多工

管線化(pipelining)和⾮管線化的差別:

【java總結】計算機網絡-HTTP【java總結】計算機網絡-HTTP篇
HTTP Pipelining其實是把多個HTTP請求放到⼀個TCP連接配接中⼀⼀發送,⽽在發送過程中不需要等 待伺服器對前⼀個請求的響應;隻不過,用戶端還是要按照發送請求的順序來接收響應!

在HTTP1.0中,發送⼀次請求時,需要等待服務端響應了才可以繼續發送請求。 在HTTP1.1中,發送⼀次請求時,不需要等待服務端響應了就可以發送請求了,但是回送資料給用戶端的時候,用戶端還是需要按照響應的順序來⼀⼀接收

是以說,⽆論是HTTP1.0還是HTTP1.1提出了Pipelining理論,還是會出現阻塞的情況。從專業的 名詞上說這種情況,叫做線頭阻塞(Head of line blocking)簡稱:HOLB

HTTP2與HTTP1.1最重要的差別就是解決了線頭阻塞的問題!其中最重要的改動是:多路複⽤ (Multiplexing)
【java總結】計算機網絡-HTTP【java總結】計算機網絡-HTTP篇
二進制協定
HTTP/1.1 版的頭資訊肯定是文本(ASCII編碼),資料體可以是文本,也可以是二進制。HTTP/2 則是一個徹底的二進制協定
資料流
HTTP/2 将每個請求或回應的所有資料包,稱為一個資料流(stream)。每個資料流都有一個獨一無二的編号。資料包發送的時候,都必須标記資料流ID,用來區分它屬于哪個資料流。另外還規定,用戶端發出的資料流,ID一律為奇數,伺服器發出的,ID為偶數。
頭資訊壓縮

HTTP 協定不帶有狀态,每次請求都必須附上所有資訊。是以,請求的很多字段都是重複的,比如Cookie和User Agent,一模一樣的内容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。

HTTP/2 對這一點做了優化,引入了頭資訊壓縮機制(header compression)。一方面,頭資訊使用gzip或compress壓縮後再發送;另一方面,用戶端和伺服器同時維護一張頭資訊表,所有字段都會存入這個表,生成一個索引号,以後就不發送同樣字段了,隻發送索引号,這樣就提高速度了。

伺服器推送
HTTP/2 允許伺服器未經請求,主動向用戶端發送資源,這叫做伺服器推送(server push)。

HTTP是不儲存狀态的協定

HTTP是⽆狀态的,也就是說,它是不對通信狀态進⾏儲存的。它并不知道之前通信的對⽅是誰。這樣 設計的⽬的就是為了讓HTTP簡單化,能夠快速處理⼤量的事務!

但是,我們經常是需要知道通路的⼈是誰,比如當使用者往購物車中添加了商品,web 應用必須在使用者浏覽别的商品的時候仍儲存購物車的狀态,以便使用者繼續往購物車中添加商品。(你說儲存在使用者的資料庫裡面,那首先得登入吧,我們平時用的京東之類的購物網站可不是這樣,未登入狀态下就可以添加購物車)于是就有了Cookie技術了。

什麼是Cookie?

cookie 是浏覽器的一種緩存機制,它可用于維持用戶端與伺服器端之間的會話。由于下面一題會講到session,是以這裡要強調cookie會将會話儲存在用戶端(session則是把會話儲存在服務端)
  1. 首先使用者在用戶端浏覽器向伺服器發起登陸請求(或者不登入,但是第一次通路同樣會給你一個cookie)
  2. 登陸成功後,服務端會把登陸的使用者資訊設定 cookie 中,傳回給用戶端浏覽器
  3. 用戶端浏覽器接收到 cookie 請求後,會把 cookie 儲存到本地(可能是記憶體,也可能是磁盤,看具體使用情況而定)
  4. 以後再次通路該 web 應用時,用戶端浏覽器就會把本地的 cookie 帶上,這樣服務端就能根據 cookie 獲得使用者資訊了

什麼是session?

剛才說的cookie一個重要概念就是儲存在本地,那如果我想區分使用者權限,有一個使用者是普通使用者,我給了他VIP1權限,并且儲存在了他的CK裡面,但是他自己改成了VIP15,然後我的網站判斷這個人擁有全部權限。。。。。于是。。。。。。

很明顯,這樣是不安全的,于是,類似的又有了一個session的機制,session把會話内容儲存在伺服器端

  1. 首先使用者在用戶端浏覽器發起登陸請求
  2. 登陸成功後,服務端會把使用者資訊儲存在服務端,并傳回一個唯一的 session 辨別給用戶端浏覽器。
  3. 用戶端浏覽器會把這個唯一的 session 辨別儲存在起來(一般儲存在ck裡面)
  4. 以後再次通路 web 應用時,用戶端浏覽器會把這個唯一的 session 辨別帶上,這樣服務端就能根據這個唯一辨別找到使用者資訊。
大家會不會有一個疑問,說生成了一個session,又儲存到了我的ck裡面,那豈不是還是不安全,但是,我們可以抓包看一下
【java總結】計算機網絡-HTTP【java總結】計算機網絡-HTTP篇
我們能從這麼一個字元串看出任何有效資訊嗎(一般來說,我們都能往伺服器存資料了,應該沒人往前台寫隐私資訊吧,emmmm~應該不會吧)他隻是給了我們一個ID,有效資訊都在伺服器,他會根據我們的ID去伺服器查找有效資訊,然後傳回對應内容。

session和cookie有什麼差別

  1. cookie 是浏覽器提供的一種緩存機制,它可以用于維持用戶端與服務端之間的會話
  2. session 指的是維持用戶端與服務端會話的一種機制,它可以通過 cookie 實作,也可以通過别的手段實作。
  3. 如果用 cookie 實作會話,那麼會話會儲存在用戶端浏覽器中
  4. 而 session 機制提供的會話是儲存在服務端的。

HTTPS協定

本塊知識對細節要求較高,還是希望大家可以了解下ssl證書,以及非對稱加密之類的概念

推薦先閱讀碼農翻身中關于https的小故事,然後再來了解https

Http的缺點

  1. 通信使用明文不對資料進行加密(内容容易被竊聽)
  2. 不驗證通信方身份(容易僞裝)
  3. 無法确定封包完整性(内容易被篡改)

不安全:大家還記得我在計算機網絡基礎篇裡面說的聯網過程嗎

從你家的網線出發,到小區的交換機,再到城市中央的路由器,再到小夥伴的小區交換機,再到小夥伴的電腦桌面。

任意一個環節都可以接入一台電腦,然後抓包,資料是可以被抓下來的。

比如我們傳輸一段 password:123456,那麼黑客就直接可以看到了

但是我們傳輸一段 password:123456,使用加密技術之後 黑客可能看到的就是 E10ADC3949BA59ABBE56E057F20F883E

是以我們應該使用加密技術,但是碼農翻身中 張大胖和Bill 的聊天,也指出了問題,如果中間人擷取了他們的公鑰,然後進行中間人攻擊,那又失去了他的安全性。

于是乎,他們把自己的公鑰交給,權威機構生成證書,權威機構在保證自己絕對安全的情況下,才能為整個網際網路的安全做背書。

ssl證書

SSL 協定就是用來解決 HTTP 傳輸過程的不安全問題,到了1999年,SSL 因為應用廣泛,已經成為網際網路上的事實标準。IETF 就在那年把 SSL 标準化。标準化之後的名稱改為 TLS(是“Transport Layer Security”的縮寫),中文叫做“傳輸層安全協定”。

很多相關的文章都把這兩者并列稱呼(SSL/TLS),因為這兩者可以視作同一個東西的不同階段。

(個人認為,大家還是喜歡把他叫做SSL,不信你去百度搜尋下SSL證書和TLS證書,看看哪個廣告多)

SSL/TLS協定的基本思路是采用公鑰加密法,也就是說,用戶端先向伺服器端索要公鑰,然後用公鑰加密資訊,伺服器收到密文後,用自己的私鑰解密。

SSL/TLS協定的基本過程是這樣的

  1. 服務端将非對稱加密的公鑰發送給用戶端;
  2. 用戶端拿着服務端發來的公鑰,對對稱加密的key做加密并發給服務端;
  3. 服務端拿着自己的私鑰對發來的密文解密,從來擷取到對稱加密的key;
  4. 二者利用對稱加密的key對需要傳輸的消息做加解密傳輸。

然後我們來看HTTPS

HTTPS

HTTPS=HTTP+SSL

HTTPS也就是披着SSL羊皮的HTTP

HTTPS相比HTTP,在請求前多了一個「握手」的環節。

Http與Https的差別

  • HTTP 明文傳輸,資料都是未加密的,安全性較差,HTTPS(SSL+HTTP) 資料傳輸過程是加密的,安全性較好。
  • 使用 HTTPS 協定需要到 CA(Certificate Authority,數字證書認證機構) 申請證書,一般免費證書較少,因而需要一定費用。證書頒發機構如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
  • HTTP 頁面響應速度比 HTTPS 快,主要是因為 HTTP 使用 TCP 三次握手建立連接配接,用戶端和伺服器需要交換 3 個包,而 HTTPS除了 TCP 的三個包,還要加上 ssl 握手需要的 9 個包,是以一共是 12 個包。
  • http 和 https 使用的是完全不同的連接配接方式,用的端口也不一樣,前者是 80,後者是 443。
  • HTTPS 其實就是建構在 SSL/TLS 之上的 HTTP 協定,是以,要比較 HTTPS 比 HTTP 要更耗費伺服器資源。

個人覺得,這個HTTPS加密流程作用成本效益不高

又廢資源又費錢(我用的免費的。。。)

而且我通路一個網站,黑客真的會在中間截獲資料嗎,我覺得更應該從源頭或者目的來截獲吧(可能是我網絡安全知識薄弱,不太懂)

而且很明顯,多了9次握手,那速度勢必會影響 emmmm。。。

在浏覽器中輸入url位址,發生了什麼?

  • 1.解析url位址,
  • 2.DNS解析
  • 3.TCP連接配接
  • 4.發送HTTP請求
  • 5.伺服器處理請求
  • 6.伺服器傳回HTTP封包
  • 7.浏覽器解析渲染頁面

1.解析該url位址的域名,浏覽器會檢查這是一個url還是查詢的關鍵字,然後自動編碼,還會做一些安全檢查

2.DNA解析的過程是遞歸的,下面以請求 www.google.com 為例:首先在本地域名伺服器中查詢IP位址,如果沒有找到的情況下,本地域名伺服器會向根域名伺服器發送一個請求,如果根域名伺服器也不存在該域名時,本地域名會向com頂級域名伺服器發送一個請求,依次類推下去。直到最後本地域名伺服器得到google的IP位址并把它緩存到本地,供下次查詢使用。從上述過程中,可以看出網址的解析是一個從右向左的過程: com -> google.com -> www.google.com。

3.HTTP協定是使用TCP作為其傳輸層協定的,當TCP出現瓶頸時,HTTP也會受到影響。

4.發送HTTP請求的過程就是建構HTTP請求封包并通過TCP協定中發送到伺服器指定端口(HTTP協定80/8080, HTTPS協定443)。HTTP請求封包是由三部分組成: 請求行, 請求報頭和請求體。請求行格式及示例如下:

Method Request-URL HTTP-Version CRLF
GET index.html HTTP/1.1
           

常用的方法有:GET, POST, PUT, DELETE, OPTIONS, HEAD

5.伺服器處理這裡可說可不說

【java總結】計算機網絡-HTTP【java總結】計算機網絡-HTTP篇

6.後端從在固定的端口接收到TCP封包開始,這一部分對應于程式設計語言中的socket。它會對TCP連接配接進行處理,對HTTP協定進行解析,并按照封包格式進一步封裝成HTTP Request對象,供上層使用。HTTP響應封包也是由三部分組成: 狀态碼, 響應報頭和響應體。

7.浏覽器是一個邊解析邊渲染的過程。首先浏覽器解析HTML檔案建構DOM樹,然後解析CSS檔案建構渲染樹,等到渲染樹建構完成後,浏覽器開始布局渲染樹并将其繪制到螢幕上。

【java總結】計算機網絡-HTTP【java總結】計算機網絡-HTTP篇

向淘寶請求首頁,怎麼提高性能

從請求、傳輸、渲染3個方面提升

一、請求

浏覽器為了減少請求傳輸,實作了自己的緩存機制。浏覽器緩存就是把一個已經請求過的Web資源拷貝一份副本存儲在浏覽器中,當再次請求相同的URL時,先去檢視緩存,如果有本地緩存,浏覽器緩存機制會根據驗證機制(Etag)和過期機制(Last-Modified)進行判斷是使用緩存,還是從伺服器傳輸資源檔案。具體流程如下圖所示:

【java總結】計算機網絡-HTTP【java總結】計算機網絡-HTTP篇

浏覽器的請求有些是并發的,有些是阻塞的,比如:圖檔、CSS、接口的請求是并發;JS檔案是阻塞的。請求JS的時候,浏覽器會中斷渲染程序,等待JS檔案加載解析完畢,再重新渲染。是以要把JS檔案放在頁面的最後。

JS也可以通過兩種方式由阻塞改成并行:一種是通過建立script标簽,插入DOM中;另一種是在Script标簽中增加async屬性。

每種浏覽器對同一域名并發的數量有限制,IE6/7是2,IE9是10,其他常見的浏覽器是6,是以減少資源請求數量和使用多域名配置資源檔案,能大大提高網站性能。

減少資源請求數量的方法,大緻有以下幾種:

1、通過打包工具,合并資源,減少資源數量。就是開發版本是很多個資源檔案,部署的時候,按類合并成幾個檔案來輸出。在實作子產品管理的同時,實作統一輸出。

2、CSS中,使用css sprite減少圖檔請求數量。

3、通過延遲加載技術,在使用者無感覺的情況下請求資源。

4、通過伺服器配置,實作一次請求,傳回多個資源檔案,如淘寶CDN那樣。

除了減少請求數量,也可以使用CDN鏡像,來減少網絡節點,實作快速響應。使用了CDN的請求,會根據使用者所處的地理位置,找尋最近的CDN節點,如果請求是新的,則從資源伺服器拷貝到節點,然後再傳回給用戶端。如果請求已經存在,則直接從節點傳回用戶端。

通過上面我們了解的緩存機制,如果我們部署上線的時候,是需要重新整理緩存的。普通緩存通過強刷就能改過來,而CDN緩存則需要通過改變URL來實作。同時我們不可能要求使用者按着Ctrl來重新整理,是以通過打包工具,在部署的時候,統一更改URL是最有效的方式。而不常變更的庫檔案,比如echart、jquery,則不建議更改。

二、傳輸

從伺服器往用戶端傳輸,可以開啟gzip壓縮來提高傳輸效率。

Gzip有從1-10的十個等級。越高壓縮的越小,但壓縮使用的伺服器硬體資源就越多。根據實踐,等級為5的時候最均衡,此時壓縮效果是100k可以壓縮成20k。

三、渲染

浏覽器在加載了html後,就會一邊解析,一邊根據解析出來的結果進行資源請求,并生成DOM樹。而加載完畢的CSS,則被渲染引擎根據生成好的DOM樹,來生成渲染樹。等所有資源解析完畢計算好layout後,向浏覽器界面繪制。随着使用者操作,JS會修改DOM節點或樣式,重新繪制和重新排列。重新繪制指的是繪制DOM節點對應的渲染節點,重新排列是指重新計算這些節點在浏覽器界面的位置。很顯然,重排是非常耗性能的。我們要做的是減少重排的次數。

生成DOM樹的時候,我們可以通過減少DOM節點來優化性能。最初都是用table布局,節點深度和數量相當複雜,性能很差。同樣CSS作為層疊樣式表,層級也不可太深,不然周遊的成本很高。另外CSS的expression屬性相當耗性能,能不用則不用。動畫效果能用CSS寫的就不用JS寫,渲染引擎不一樣,性能損耗也不一樣。

上面說的是解析渲染的過程,我們再接着說說使用者互動操作的過程。使用者操作就會導緻重繪和重排,重排一定會引起重繪,而重繪不一定會引起重排。到底怎樣會引起重排呢?簡單的定義,DOM結構的變化,以及DOM樣式中幾何屬性的變化,就會導緻重排。幾何屬性顧名思義,就是寬、高、邊框、外更新檔、内更新檔等俗稱盒模型的屬性。同時還有offset之類的邊距屬性。

重排是最耗能的,減少重排的方法有:

1、如果需要多次改變DOM,則先在記憶體中改變,最後一次性的插入到DOM中。

2、同上一條,如果多次改變樣式,合成一條,再插入DOM中。

3、由于position的值為absoute和fixed時候,是脫離文檔流的,操作此類DOM節點,不會引起整頁重排。是以動畫元素設定position使其脫離文檔流。

4、當DOM節點的display等于none的時候,是不會存在于渲染樹的,是以如果有比較複雜的操作,先使其display等于none,等待所有操作完畢後,再将display設成block,這樣就隻重排兩次。

5、擷取會導緻重排的屬性值時,存入變量,再次使用時就不會再次重排。擷取這些屬性會導緻重排:offsetTop、offsetLeft、offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

以上就是浏覽器如何把資源變成肉眼所見的頁面的,除了上述根據浏覽器流程而總結出來的性能優化,我們還需要看看javascript作為程式,需要的優化。先來看看javascript的垃圾回收機制。

Javascript的引擎會在固定的時間間隔,将不再使用的局部變量登出掉,釋放其所占的記憶體。而閉包的存在,将使引用一直存在,無法被釋放掉。全局變量的生命周期直至浏覽器解除安裝頁面才會結束。是以一般來講,記憶體溢出就是由于全局變量的不釋放和閉包引起。為了防止記憶體溢出,我們可以做的方法有:

1、業務代碼放在匿名立即執行函數裡面,執行完畢會立即釋放掉。

2、少用全局變量,同時用完的變量手動登出掉。

3、使用回調來代替閉包通路内部屬性

4、當不可避免使用閉包時,慎重的對待其中的細節。不用的時候登出掉。

5、通過浏覽器自帶的工具profiles,來檢查記憶體活動情況。如果是波浪型的,說明正常。如果是傾斜式漸進上漲的,說明有記憶體不會被釋放,需要檢查相應的函數。

最後再說一點,函數裡傳回異步取的值,經常有人這麼:

Var getList = function(){ $.ajax().then(function(data){

  Return data;

}) };

Var users = getList();
           

毫無疑問,由于函數内的傳回是異步的,是以傳回隻能是undefined,而不是想要的data。于是為了實作傳回data,就把ajax的async屬性設定成了false,由異步改為同步,來擷取到data。然而最大的問題來了,同步是會中斷渲染程序的,也就是請求傳回的等待中,整個頁面是卡死的,使用者操作也不會有響應。這個問題真正的解決方案是傳回promise對象,而不是把異步改成同步。