html 面試相關知識點匯總


知識點匯總

HTML5新特性,語義化

DTD

Document type Definition指為了程序間的數據交換而建立的關於標識符的一套語法規則

SGML,HTML,XML

  • SGML 即Standard Globalized Markup Language 是用來定義標准的標記語言,簡單的說,就是定義文檔的元語言。
  • HTML 是基於SGML的超鏈接語言,可以用於創建Web頁面。在DTD內部定義了標簽的規則,DTD就是使用SGML 語言創建的。
  • XML 是從SGML 衍生而來的,它主要處理互聯網方面的需求,HTML 有很多限制,XML 是SGML 的子集,可用於表示數據。

DOC類型

創建HTML頁面時:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

這句代碼簡單的介紹了HTML 版本號,有了Doctype,就引入了對應的DTD(定義了HTML文檔的組織結構),在頁面中添加的所有標簽才會是合法的,簡單的說DTD 就是定義HTML的語法規則。
即使在沒有引入DTD的情況下,很多瀏覽器也可以識別HTML元素,因為它們自身包含對HTML 元素的定義,這就是為什么很多開發人員沒有感受到DTD 的存在。

HTML5 與之前的版本區別

HTML5不是基於SGML 語言的,因此不需要DTD ,它是一種全新的標記語言,有自己的解析規則,HTML5的語法規則與之前版本有很大的差別,可以稱的上是一種全新的語言。
HTML5 的Doctype 非常簡單:

<!DOCTYPE html>

HTML5與HTML4.01之間的差異

在 HTML 4.01 中有三種 <!DOCTYPE> 聲明。在 HTML5 中只有一種:

  • HTML 4.01 Strict 該 DTD 包含所有 HTML 元素和屬性,但不包括展示性的和棄用的元素(比如 font)。不允許框架集(Framesets)。
  • HTML 4.01 Transitional,該 DTD 包含所有 HTML 元素和屬性,包括展示性的和棄用的元素(比如 font)。不允許框架集(Framesets)。
  • HTML 4.01 Frameset,該 DTD 等同於 HTML 4.01 Transitional,但允許框架集內容。

HTML5 新特性

  1. 理解新的頁面結構語義
    HTML 舊版本並沒有標准的文檔定義規則,比如如何定義文檔Header或Footer等,很多人都在使用div來修飾一些CSS ,常常會導致不一致性。
    HTML5 定義標准tag如Header,Footer,nav,FlipCaption等。這些標簽可使得標記語言更有意義。
    注意: 這些標簽不提供特殊的渲染功能,僅僅使的HTML 文檔結構更具有意義。

  2. 新的輸入屬性
    之前為了獲得不同的UI元素,如DatePicker,range Picker,color Picker等,會使用不同的類庫。
    HTML5 為輸入元素引入了新屬性“type”,看以下示例:

<input type="number" name="MyNuberElement" id="MyNumberElement" />
<input type="range" name="MyRangeElement" id="MyRangeElement"/>
<input type="color" id="MyColorElement" name="MyColorElement" />
<input type="date" id="MyDateElement" name="MyDateElement" />
<input type="time" id="MyTimeElement" name="MyTimeElement"/>

placeholder

HTML5的表單驗證屬性
  1. Audio,video等多媒體支持

  2. drag,drop,geolocation,本地存儲localStorage,web worker

HTML的語義化

(1)HTML語義化讓頁面的內容結構化,結構更清晰,便於對瀏覽器、搜索引擎解析;
(2)即使在沒有樣式CSS的情況下也能以一種文檔格式顯示,並且是容易閱讀的;
(3)搜索引擎的爬蟲也依賴於HTML標記來確定上下文和各個關鍵字的權重,有利於SEO;
(4)使閱讀源代碼的人更容易將網站分塊,便於閱讀、維護和理解。

瀏覽器的標准模式和怪異模式

所謂的標准模式是指,瀏覽器按W3C標准解析執行代碼;怪異模式則是使用瀏覽器自己的方式解析執行代碼,因為不同瀏覽器解析執行的方式不一樣,所以我們稱之為怪異模式。瀏覽器解析時到底使用標准模式還是怪異模式,與你網頁中的DTD聲明直接相關,DTD聲明定義了標准文檔的類型(標准模式解析)文檔類型,會使瀏覽器使用相應的方式加載網頁並顯示,忽略DTD聲明,將使網頁進入怪異模式(quirks mode)。

如果你的網頁代碼不含有任何聲明,那么瀏覽器就會采用怪異模式解析,便是如果你的網頁代碼含有DTD聲明,瀏覽器就會按你所聲明的標准解析。

標准模式中IE6不認識!important聲明,IE7、IE8、Firefox、Chrome等瀏覽器認識;而在怪異模式中,IE6/7/8都不認識!important聲明,這只是區別的一種,還有很多其它區別。所以,要想寫出跨瀏覽器CSS,你最好采用標准模式。

document對象有個屬性compatMode,它有兩個值:

  • BackCompat 對應quirks mode
  • CSS1Compat 對應strict mode

最大的異同點是對於盒模型中內容的width和height的計算方式不同

瀏覽器模式

IE11改名為“用戶代理字符串”。就是用來設置navigator.userAgent和navigator.appVersion.

它唯一需要注意的是,在不同的IE版本中,它與文檔模式的關系可不相同。

IE89中,倘若瀏覽器模式被設置為Internet Explorer7,那么文檔模式的只能設置為7,6,5;

IE11中,用戶代理字符串設置和文檔模式可謂是沒有半毛錢關系。

文檔模式

文檔模式用於設置瀏覽器的渲染模式和對應的JS引擎特性.

對於以Webkit、Molliza等作為內核的瀏覽器來說,DOM樹的解析、渲染,JS的API等主要與內核版本掛鈎;而對於IE瀏覽器而言,這些從IE6開始就跟文檔模式掛鈎了。

  1. 怪異模式
    IE6789的是IE5.5的文檔模式,IE10+和Chrome等瀏覽器是W3C規范的怪異模式。

  2. 標准模式 (非怪異模式)
    W3C標准的文檔模式,但各瀏覽器的實現階段不盡相同。

  3. 准標准模式 (有限怪異模式)
    由於該模式離W3C標准仍然有一段距離,因此被稱作准標准模式(或有限怪異模式)。IE6、7的標准模式實際上就是准標准模式,而IE8+才有實質上的標准模式

兼容模式

在兼容模式中,頁面以寬松的向后兼容的方式顯示,模擬老式瀏覽器的行為以防止站點無法工作。當DTD沒有定義時,即開啟兼容也稱混雜模式.

js的嚴格模式

ECMASript5最早引入了"嚴格模式",通過嚴格模式,可以在函數內部選擇進行較為嚴格的全局或局部的錯誤條件檢測.使用嚴格模式的好處就是可以提早知道代碼中存在的錯誤.為未來的規范定義做鋪墊.

將"use strict"放在腳本文件的第一行,則整個腳本都將以"嚴格模式"運行。

將"use strict"放在函數體的第一行,則整個函數以"嚴格模式"運行。

使用data-*的好處

data-* 屬性用於存儲私有頁面后應用的自定義數據。
data-* 屬性可以在所有的 HTML 元素中嵌入數據。
自定義的數據可以讓頁面擁有更好的交互體驗(不需要使用 Ajax 或去服務端查詢數據)。
通過HTML5的規范之后,可以根據element的dataset屬性,直接獲取數據.

data-* 屬性是 HTML5 新增的。

meta標簽

<meta> 元素可提供有關頁面的元信息(meta-information),比如針對搜索引擎和更新頻度的描述和關鍵詞。
<meta> 標簽位於文檔的頭部,不包含任何內容。<meta> 標簽的屬性定義了與文檔相關聯的名稱/值對。

meta標簽根據屬性的不同,可分為兩大部分:http-equiv 和 name 屬性。

  • http-equiv:相當於http的文件頭作用,它可以向瀏覽器傳回一些有用的信息,以幫助瀏覽器正確地顯示網頁內容。
  • name屬性:主要用於描述網頁,與之對應的屬性值為content,content中的內容主要是便於瀏覽器,搜索引擎等機器人識別,等等。

常用的有viewport,charset,lang;

viewport content 參數:

  • width viewport 寬度(數值/device-width)
  • height viewport 高度(數值/device-height)
  • initial-scale 初始縮放比例
  • maximum-scale 最大縮放比例
  • minimum-scale 最小縮放比例
  • user-scalable 是否允許用戶縮放(yes/no)

meta viewport原理

桌面上視口寬度等於瀏覽器寬度,但在手機上有所不同。

  1. 布局視口
    手機上為了容納為桌面瀏覽器設計的網站,默認布局視口寬度遠大於屏幕寬度,為了讓用戶看到網站全貌,它會縮小網站

  2. 視覺視口
    屏幕的可視區域,即物理像素尺寸

  3. 理想視口
    當網站是為手機准備的時候使用。通過meta來聲明。早期iPhone理想視口為320x480px

所以,在沒有縮放的情況下,屏幕的CSS像素寬度其實是指理想視口的寬度,而meta標簽:

<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>

指定了布局視口=理想視口,並且禁止縮放。所以添上width=device-width的 viewport meta后頁面變大了(一開始頁面內容小得看不清),實際上是布局視口變小了。

HTML5廢棄的元素

表現性元素

  • basefont
  • big
  • center
  • font
  • s
  • strike
  • tt
  • u

框架類元素

  • frame
  • frameset
  • noframes

屬性值

  • align
  • body標簽上的link、vlink、alink、text屬性
  • bgcolor
  • height和width
  • iframe元素上的scrolling屬性
  • valign
  • hspace和vspace
  • table標簽上的cellpadding、cellspacing和border屬性
  • header標簽上的profile屬性
  • 鏈接標簽a上的target屬性
  • img和iframe元素的longdesc屬性

瀏覽器內核

Trident(ie內核);

Gecko(Firefox內核);

Webkit(chrome內核,safari內核);

Blink(chrome新內核);

瀏覽器兼容寫法

CSS hack和filter原理

利用瀏覽器自身的bug來實現特定瀏覽器的樣式
利用瀏覽器對CSS的完善度來實現,例如某些CSS規則或語法的支持程度,原理類似目前我們經常使用的 -webkit- 之類的屬性;

IE條件注釋

IE的條件注釋僅僅針對IE瀏覽器,對其他瀏覽器無效;例如下面的語法:

<!-- [if IE]>
  		//你想要執行的代碼
<![endif]-->
<!-- [if lt IE 8]>
  			//你想要執行的代碼
<![endif]-->
<!-- [if ! IE 8]>
  		//你想要執行的代碼
<![endif]-->

!important 關鍵字

!important 在css中是聲明擁有最高優先級,也就是說,不管css的其他優先級,只要!important出現,他的優先級就最高!遨游1.6及更低版本、IE6及更低版本瀏覽器不能識別它。盡管這個!important 很實用,但是非到必要的時刻,不要使用它!

屬性過濾器(較為常用的hack方法)

針對不同的IE瀏覽器,可以使用不同的字符來讓特定的版本的IE瀏覽器進行樣式控制。

字符 例子 說明
_ _color:red ie6識別
* *color:red ie6/7可以識別
\9 color:red\9 ie8以下可以識別

更多hack寫法

CSS兼容方案

a標簽css順序

link -> visited -> hover -> active

24位的png圖片

IE6不支持透明咋辦?使用png透明圖片唄,但是需要注意的是24位的PNG圖片在IE6是不支持的,解決方案有兩種:

  • 使用8位的PNG圖片
  • 為IE6准備一套特殊的圖片

透明度

opacity: 0.8; //通用
filter: alpha(opacity=80); //IE
filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=80); //IE6的寫法

IE6雙邊距

行內屬性設置了塊級屬性(display: block;)后,會產生雙倍邊距。
解決方案是在添加一個 display: inline; 或者 display: table;

js兼容

ie監聽方法:attachEvent()和detachEvent();

普通監聽方法:addEventListener()和removeEventListener();

css js放置位置和原因

瀏覽器本身是多線程的:

  • javascript引擎線程
  • 界面渲染線程
  • 瀏覽器事件觸發線程
  • Http請求線程

而JS運行在瀏覽器中,是單線程的,每個瀏覽器頁面就是一個JS線程。

當我們在瀏覽器的地址欄里輸入一個url地址,訪問一個新頁面時候,頁面展示的快慢就是由一個單線程所控制,這個線程叫做UI線程,UI線程會根據頁面里資源(資源是html文件、圖片、css等)書寫的先后順序,它會按照資源的類型發起http請求來獲取資源,當http請求處理完畢也就意味着資源加載結束。

但是碰到javascript文件則不同,它的加載過程被分為兩步,第一步和加載css文件和圖片一樣,就是執行一個http請求下載外部的js文件,但是javascript完成http操作后並不意味操作完畢,UI線程就會通知javascript引擎線程來執行它,如果javascript代碼執行時間過長,那么用戶就會明顯感覺到頁面的延遲。

為什么瀏覽器不能把javascript代碼的加載過程拆分為下載和執行兩個並行的過程,這樣就可以充分利用時間完成http請求,這樣不是就能提升頁面的加載效率了嗎?答案當然是否定的。

因為javascript是一個圖靈完備的編程語言,js代碼是有智力的,它除了可以完成邏輯性的工作,還可以通過操作頁面元素來改變頁面的UI渲染,如果我們忽略javascript對網頁UI界面渲染的影響,讓它下載和運行是分開的(也可以理解為js代碼可以延遲執行),結果會造成頁面展示的混亂,或多次重繪。很顯然,這樣的做法是不合適的,因此,js腳本的下載和執行必須是一個完整的操作,是不能被割裂的。

漸進式渲染

對渲染進行分割 從具體的使用的場景, 不同的 Level 實際上對應不同的頁面內容.

論壇是一個比較清晰的例子, 想象一個論壇:
網頁的靜態部分

  • HTML 固定的內容, 比如導航欄和底部
  • 頁面首屏的內容, 比如一個論壇的話題
  • 頁面首屏看不到的內容, 比如話題下面多少回復
  • 切換路由才會顯示的頁面, 比如導航的另一個頁面

對於這樣的情況, 顯然有若干種可行的渲染分割的方案

全在客戶端渲染

1, 2, 3 在服務端渲染, 4 等到用戶點擊從瀏覽器抓
1, 2 在服務器渲染, 評論由客戶端加載
只有 1 在服務端渲染, 動態的數據全部由客戶端抓取.
而這些方案對於服務端來說, 性能的開銷各不相同, 形成一個梯度,
而最后一種情況, 服務端預編譯頁面就好了, 幾乎沒有渲染負擔.
根據實際的場景, 可以有更多 Level 可以設計.. 只是沒這么簡單罷了.

html模板語言

通過重新定義html片段規則,解析之后,生成可被瀏覽器所識別的html片段,就是html模板語言.

離線存儲

在線情況下,瀏覽器發現html頭部有manifest屬性,它會請求manifest文件,如果是第一次訪問app,那么瀏覽器就會根據manifest文件的內容下載相應的資源並且進行離線存儲。如果已經訪問過app並且資源已經離線存儲了,那么瀏覽器就會使用離線的資源加載頁面,然后瀏覽器會對比新的manifest文件與舊的manifest文件,如果文件沒有發生改變,就不做任何操作,如果文件改變了,那么就會重新下載文件中的資源並進行離線存儲。
離線情況下,瀏覽器就直接使用離線存儲的資源。

  1. oncached:當離線資源存儲完成之后觸發這個事件,這個是文檔的說法,我在Chrome上面測試的時候並沒有觸發這個事件。

  2. onchecking:當瀏覽器對離線存儲資源進行更新檢查的時候會觸發這個事件

  3. ondownloading:當瀏覽器開始下載離線資源的時候會觸發這個事件

  4. onprogress:當瀏覽器在下載每一個資源的時候會觸發這個事件,每下載一個資源就會觸發一次。

  5. onupdateready:當瀏覽器對離線資源更新完成之后會觸發這個事件

  6. onnoupdate:當瀏覽器檢查更新之后發現沒有資源更新的時候觸發這個事件

瀏覽器中的緩存

以三個部分來把瀏覽器的緩存機制說清楚:

  • 強緩存
  • 協商緩存
  • 緩存位置

強緩存

瀏覽器中的緩存作用分為兩種情況,一種是需要發送HTTP請求,一種是不需要發送。
首先是檢查強緩存,這個階段不需要發送HTTP請求。
如何來檢查呢?通過相應的字段來進行,但是說起這個字段就有點門道了。
在HTTP/1.0和HTTP/1.1當中,這個字段是不一樣的。在早期,也就是HTTP/1.0時期,使用的是Expires,而HTTP/1.1使用的是Cache-Control。讓我們首先來看看Expires。

Expires

Expires即過期時間,存在於服務端返回的響應頭中,告訴瀏覽器在這個過期時間之前可以直接從緩存里面獲取數據,無需再次請求。比如下面這樣:

Expires: Wed, 22 Nov 2019 08:41:00 GMT

表示資源在2019年11月22號8點41分過期,過期了就得向服務端發請求。
這個方式看上去沒什么問題,合情合理,但其實潛藏了一個坑,那就是服務器的時間和瀏覽器的時間可能並不一致,那服務器返回的這個過期時間可能就是不准確的。因此這種方式很快在后來的HTTP1.1版本中被拋棄了。

Cache-Control

在HTTP1.1中,采用了一個非常關鍵的字段:Cache-Control。這個字段也是存在於
它和Expires本質的不同在於它並沒有采用具體的過期時間點這個方式,而是采用過期時長來控制緩存,對應的字段是max-age。比如這個例子:

Cache-Control:max-age=3600

代表這個響應返回后在 3600 秒,也就是一個小時之內可以直接使用緩存。
如果你覺得它只有max-age一個屬性的話,那就大錯特錯了。
它其實可以組合非常多的指令,完成更多場景的緩存判斷, 將一些關鍵的屬性列舉如下:

  • public: 客戶端和代理服務器都可以緩存。因為一個請求可能要經過不同的代理服務器最后才到達目標服務器,那么結果就是不僅僅瀏覽器可以緩存數據,中間的任何代理節點都可以進行緩存。
  • private: 這種情況就是只有瀏覽器能緩存了,中間的代理服務器不能緩存。
  • no-cache: 跳過當前的強緩存,發送HTTP請求,即直接進入協商緩存階段。
  • no-store:非常粗暴,不進行任何形式的緩存。
  • s-maxage:這和max-age長得比較像,但是區別在於s-maxage是針對代理服務器的緩存時間。

值得注意的是,當Expires和Cache-Control同時存在的時候,Cache-Control會優先考慮。
當然,還存在一種情況,當資源緩存時間超時了,也就是強緩存失效了,接下來怎么辦?沒錯,這樣就進入到第二級屏障——協商緩存了。

協商緩存

強緩存失效之后,瀏覽器在請求頭中攜帶相應的緩存tag來向服務器發請求,由服務器根據這個tag,來決定是否使用緩存,這就是協商緩存。
具體來說,這樣的緩存tag分為兩種: Last-Modified 和 ETag。這兩者各有優劣,並不存在誰對誰有絕對的優勢,跟上面強緩存的兩個 tag 不一樣。

Last-Modified

即最后修改時間。在瀏覽器第一次給服務器發送請求后,服務器會在響應頭中加上這個字段。
瀏覽器接收到后,如果再次請求,會在請求頭中攜帶If-Modified-Since字段,這個字段的值也就是服務器傳來的最后修改時間。

服務器拿到請求頭中的If-Modified-Since的字段后,其實會和這個服務器中該資源的最后修改時間對比:

如果請求頭中的這個值小於最后修改時間,說明是時候更新了。返回新的資源,跟常規的HTTP請求響應的流程一樣。
否則返回304,告訴瀏覽器直接用緩存。

ETag

ETag 是服務器根據當前文件的內容,給文件生成的唯一標識,只要里面的內容有改動,這個值就會變。服務器通過響應頭把這個值給瀏覽器。
瀏覽器接收到ETag的值,會在下次請求時,將這個值作為If-None-Match這個字段的內容,並放到請求頭中,然后發給服務器。
服務器接收到If-None-Match后,會跟服務器上該資源的ETag進行比對:

如果兩者不一樣,說明要更新了。返回新的資源,跟常規的HTTP請求響應的流程一樣。
否則返回304,告訴瀏覽器直接用緩存。

兩者對比

在精准度上,ETag優於Last-Modified。優於 ETag 是按照內容給資源上標識,因此能准確感知資源的變化。而 Last-Modified 就不一樣了,它在一些特殊的情況並不能准確感知資源變化,主要有兩種情況:

編輯了資源文件,但是文件內容並沒有更改,這樣也會造成緩存失效。
Last-Modified 能夠感知的單位時間是秒,如果文件在 1 秒內改變了多次,那么這時候的 Last-Modified 並沒有體現出修改了。

在性能上,Last-Modified優於ETag,也很簡單理解,Last-Modified僅僅只是記錄一個時間點,而 Etag需要根據文件的具體內容生成哈希值。

另外,如果兩種方式都支持的話,服務器會優先考慮ETag。

緩存位置

前面我們已經提到,當強緩存命中或者協商緩存中服務器返回304的時候,我們直接從緩存中獲取資源。那這些資源究竟緩存在什么位置呢?
瀏覽器中的緩存位置一共有四種,按優先級從高到低排列分別是:

  • Service Worker
  • Memory Cache
  • Disk Cache
  • Push Cache

Service Worker

Service Worker 借鑒了 Web Worker的 思路,即讓 JS 運行在主線程之外,由於它脫離了瀏覽器的窗體,因此無法直接訪問DOM。雖然如此,但它仍然能幫助我們完成很多有用的功能,比如離線緩存、消息推送和網絡代理等功能。其中的離線緩存就是 Service Worker Cache。
Service Worker 同時也是 PWA 的重要實現機制,關於它的細節和特性,我們將會在后面的 PWA 的分享中詳細介紹。

Memory Cache 和 Disk Cache

Memory Cache指的是內存緩存,從效率上講它是最快的。但是從存活時間來講又是最短的,當渲染進程結束后,內存緩存也就不存在了。
Disk Cache就是存儲在磁盤中的緩存,從存取效率上講是比內存緩存慢的,但是他的優勢在於存儲容量和存儲時長。稍微有些計算機基礎的應該很好理解,就不展開了。
好,現在問題來了,既然兩者各有優劣,那瀏覽器如何決定將資源放進內存還是硬盤呢?主要策略如下:

比較大的JS、CSS文件會直接被丟進磁盤,反之丟進內存
內存使用率比較高的時候,文件優先進入磁盤

Push Cache

即推送緩存,這是瀏覽器緩存的最后一道防線。它是 HTTP/2 中的內容,雖然現在應用的並不廣泛,但隨着 HTTP/2 的推廣,它的應用越來越廣泛。

總結

對瀏覽器的緩存機制來做個簡要的總結:
首先通過 Cache-Control 驗證強緩存是否可用

如果強緩存可用,直接使用
否則進入協商緩存,即發送 HTTP 請求,服務器通過請求頭中的If-Modified-Since或者If-None-Match字段檢查資源是否更新

若資源更新,返回資源和200狀態碼
否則,返回304,告訴瀏覽器直接從緩存獲取資源。

HTTPS為什么讓數據傳輸更安全

談到HTTPS, 就不得不談到與之相對的HTTP。HTTP的特性是明文傳輸,因此在傳輸的每一個環節,數據都有可能被第三方竊取或者篡改,具體來說,HTTP 數據經過 TCP 層,然后經過WIFI路由器、運營商和目標服務器,這些環節中都可能被中間人拿到數據並進行篡改,也就是我們常說的中間人攻擊。

為了防范這樣一類攻擊,我們不得已要引入新的加密方案,即 HTTPS。

HTTPS並不是一個新的協議, 而是一個加強版的HTTP。其原理是在HTTP和TCP之間建立了一個中間層,當HTTP和TCP通信時並不是像以前那樣直接通信,直接經過了一個中間層進行加密,將加密后的數據包傳給TCP, 響應的,TCP必須將數據包解密,才能傳給上面的HTTP。這個中間層也叫安全層。安全層的核心就是對數據加解密。

接下來我們就來剖析一下HTTPS的加解密是如何實現的。

對稱加密和非對稱加密

概念

首先需要理解對稱加密和非對稱加密的概念,然后討論兩者應用后的效果如何。
對稱加密是最簡單的方式,指的是加密和解密用的是同樣的密鑰。
而對於非對稱加密,如果有 A、 B 兩把密鑰,如果用 A 加密過的數據包只能用 B 解密,反之,如果用 B 加密過的數據包只能用 A 解密。

加解密過程

接着我們來談談瀏覽器和服務器進行協商加解密的過程。
首先,瀏覽器會給服務器發送一個隨機數client_random和一個加密的方法列表。
服務器接收后給瀏覽器返回另一個隨機數server_random和加密方法。
現在,兩者擁有三樣相同的憑證: client_random、server_random和加密方法。
接着用這個加密方法將兩個隨機數混合起來生成密鑰,這個密鑰就是瀏覽器和服務端通信的暗號。

對稱加密和非對稱加密的結合

可以發現,對稱加密和非對稱加密,單獨應用任何一個,都會存在安全隱患。那我們能不能把兩者結合,進一步保證安全呢?
其實是可以的,演示一下整個流程:

  • 瀏覽器向服務器發送client_random和加密方法列表。
  • 服務器接收到,返回server_random、加密方法以及公鑰。
  • 瀏覽器接收,接着生成另一個隨機數pre_random, 並且用公鑰加密,傳給服務器。(敲黑板!重點操作!)
  • 服務器用私鑰解密這個被加密后的pre_random。

現在瀏覽器和服務器有三樣相同的憑證:client_random、server_random和pre_random。然后兩者用相同的加密方法混合這三個隨機數,生成最終的密鑰。

然后瀏覽器和服務器盡管用一樣的密鑰進行通信,即使用對稱加密。
這個最終的密鑰是很難被中間人拿到的,為什么呢? 因為中間人沒有私鑰,從而拿不到pre_random,也就無法生成最終的密鑰了。

回頭比較一下和單純的使用非對稱加密, 這種方式做了什么改進呢?本質上是防止了私鑰加密的數據外傳。單獨使用非對稱加密,最大的漏洞在於服務器傳數據給瀏覽器只能用私鑰加密,這是危險產生的根源。利用對稱和非對稱加密結合的方式,就防止了這一點,從而保證了安全。

添加數字證書

盡管通過兩者加密方式的結合,能夠很好地實現加密傳輸,但實際上還是存在一些問題。黑客如果采用 DNS 劫持,將目標地址替換成黑客服務器的地址,然后黑客自己造一份公鑰和私鑰,照樣能進行數據傳輸。而對於瀏覽器用戶而言,他是不知道自己正在訪問一個危險的服務器的。

事實上HTTPS在上述結合對稱和非對稱加密的基礎上,又添加了數字證書認證的步驟。其目的就是讓服務器證明自己的身份。

傳輸過程

為了獲取這個證書,服務器運營者需要向第三方認證機構獲取授權,這個第三方機構也叫CA(Certificate Authority), 認證通過后 CA 會給服務器頒發數字證書。
這個數字證書有兩個作用:

服務器向瀏覽器證明自己的身份。
把公鑰傳給瀏覽器。

這個驗證的過程發生在什么時候呢?

當服務器傳送server_random、加密方法的時候,順便會帶上數字證書(包含了公鑰), 接着瀏覽器接收之后就會開始驗證數字證書。如果驗證通過,那么后面的過程照常進行,否則拒絕執行。

現在我們來梳理一下HTTPS最終的加解密過程:

尾語

相關知識點僅供參考,具有一定的時效性,博主比較懶,博客僅做一個記錄,更新的內容會在github里https://github.com/leomYili/my-learning-notes/tree/master/interview


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM