2022年我的面試萬字總結(jié)(瀏覽器網(wǎng)絡(luò)篇)

一、HTTP
1. GET和POST的請求的區(qū)別
Post 和 Get 是 HTTP 請求的兩種方法,其區(qū)別如下:

「應用場景:」 (GET 請求是一個「冪等」的請求)一般 Get 請求用于對服務器資源不會產(chǎn)生影響的場景,比如說請求一個網(wǎng)頁的資源。(而 Post 不是一個「冪等」的請求)一般用于對服務器資源會產(chǎn)生影響的情景,比如注冊用戶這一類的操作。(「冪等是指一個請求方法執(zhí)行多次和僅執(zhí)行一次的效果完全相同」)
「是否緩存:」 因為兩者應用場景不同,瀏覽器一般會對 Get 請求緩存,但很少對 Post 請求緩存。
「傳參方式不同:」 Get 通過查詢字符串傳參,Post 通過請求體傳參。
「安全性:」 Get 請求可以將請求的參數(shù)放入 url 中向服務器發(fā)送,這樣的做法相對于 Post 請求來說是不太安全的,因為請求的 url 會被保留在歷史記錄中。
「請求長度:」 瀏覽器由于對 url 長度的限制,所以會影響 get 請求發(fā)送數(shù)據(jù)時的長度。這個限制是瀏覽器規(guī)定的,并不是 RFC 規(guī)定的。
「參數(shù)類型:」 get參數(shù)只允許ASCII字符,post 的參數(shù)傳遞支持更多的數(shù)據(jù)類型(如文件、圖片)。
2. POST和PUT請求的區(qū)別
PUT請求是向服務器端發(fā)送數(shù)據(jù),從而修改數(shù)據(jù)的內(nèi)容,但是不會增加數(shù)據(jù)的種類等,也就是說無論進行多少次PUT操作,其結(jié)果并沒有不同。(可以理解為時「更新數(shù)據(jù)」)

POST請求是向服務器端發(fā)送數(shù)據(jù),該請求會改變數(shù)據(jù)的種類等資源,它會創(chuàng)建新的內(nèi)容。(可以理解為是「創(chuàng)建數(shù)據(jù)」)

為什么post請求會發(fā)送兩次請求?
1.第一次請求為options預檢請求,狀態(tài)碼為:204

作用1: 詢問服務器是否支持修改的請求頭,如果服務器支持,則在第二次中發(fā)送真正的請求
作用2: 檢測服務器是否為同源請求,是否支持跨域
作用:

2.第二次為真正的post請求

3. 常見的HTTP請求頭和響應頭
HTTP Request Header
Accept:瀏覽器能夠處理的內(nèi)容類型
Accept-Charset:瀏覽器能夠顯示的字符集
Accept-Encoding:瀏覽器能夠處理的壓縮編碼
Accept-Language:瀏覽器當前設(shè)置的語言
Connection:瀏覽器與服務器之間連接的類型
Cookie:當前頁面設(shè)置的任何Cookie
Host:發(fā)出請求的頁面所在的域
Referer:發(fā)出請求的頁面的URL
User-Agent:瀏覽器的用戶代理字符串
HTTP Responses Header
Date:表示消息發(fā)送的時間,時間的描述格式由rfc822定義
server:服務器名稱
Connection:瀏覽器與服務器之間連接的類型
Cache-Control:控制HTTP緩存
content-type:表示后面的文檔屬于什么MIME類型
Content-Type
「常見的 Content-Type 屬性值有以下四種:」

(1)application/x-www-form-urlencoded:瀏覽器的原生 form 表單,如果不設(shè)置 enctype 屬性,那么最終就會以 application/x-www-form-urlencoded 方式提交數(shù)據(jù)。該種方式提交的數(shù)據(jù)放在 body 里面,數(shù)據(jù)按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL轉(zhuǎn)碼。

(2)multipart/form-data:該種方式也是一個常見的 POST 提交方式,通常表單上傳文件時使用該種方式。

(3)application/json:服務器消息主體是序列化后的 JSON 字符串。

(4)text/xml:該種方式主要用來提交 XML 格式的數(shù)據(jù)。

4. HTTP狀態(tài)碼304是多好還是少好
「為什么會有304」

服務器為了提高網(wǎng)站訪問速度,對之前訪問的部分頁面指定緩存機制,當客戶端在此對這些頁面進行請求,服務器會根據(jù)緩存內(nèi)容判斷頁面與之前是否相同,若相同便直接返回304,此時客戶端調(diào)用緩存內(nèi)容,不必進行二次下載。

狀態(tài)碼304不應該認為是一種錯誤,而是對客戶端「有緩存情況下」服務端的一種響應。

搜索引擎蜘蛛會更加青睞內(nèi)容源更新頻繁的網(wǎng)站。通過特定時間內(nèi)對網(wǎng)站抓取返回的狀態(tài)碼來調(diào)節(jié)對該網(wǎng)站的抓取頻次。若網(wǎng)站在一定時間內(nèi)一直處于304的狀態(tài),那么蜘蛛可能會降低對網(wǎng)站的抓取次數(shù)。相反,若網(wǎng)站變化的頻率非常之快,每次抓取都能獲取新內(nèi)容,那么日積月累,的回訪率也會提高。

「產(chǎn)生較多304狀態(tài)碼的原因:」

頁面更新周期長或不更新
純靜態(tài)頁面或強制生成靜態(tài)html
「304狀態(tài)碼出現(xiàn)過多會造成以下問題:」

網(wǎng)站快照停止;
收錄減少;
權(quán)重下降。
5. 常見的HTTP請求方法
GET: 向服務器獲取數(shù)據(jù);
POST:發(fā)送數(shù)據(jù)給服務器,通常會造成服務器資源的新增修改;
PUT:用于全量修改目標資源(看接口,也可以用于添加);
PATCH:用于對資源進行部分修改
DELETE:用于刪除指定的資源;
HEAD:獲取報文首部,與GET相比,不返回報文主體部分;使用場景是比如下載一個大文件前,先獲取其大小再決定是否要下載,以此可以節(jié)約寬帶資源
OPTIONS:(瀏覽器自動執(zhí)行)、詢問支持的請求方法,用來跨域請求、預檢請求、判斷目標是否安全;
CONNECT:要求在與代理服務器通信時建立「管道」,使用「管道」進行TCP通信;(把服務器作為跳板,讓服務器代替用戶去訪問其他網(wǎng)頁,之后把數(shù)據(jù)原原本本的返回給用戶)
TRACE: 該方法會讓服務器原樣返回任意客戶端請求的信息內(nèi)容,主要?于測試或診斷。
6. 說說Ajax組成部分
Ajax(阿賈克斯):全稱 Asynchronous Javascript And XML(異步的js與xml)

說人話:「用js發(fā)送異步的網(wǎng)絡(luò)請求」

A : Asynchronous 異步

J:Javascript

A :And

X : XML 與 XMLHttpRequest

在JSON沒有出來以前, 網(wǎng)絡(luò)傳輸主要以XML格式數(shù)據(jù)為主。后來JSON問世,逐漸取代XML。但是由于ajax技術(shù)出來的比json早,因此xml這個稱呼一直保留至今
XML :解決跨平臺數(shù)據(jù)傳輸。

7. 請介紹一下XMLHTTPRequest對象
「Ajax的核心是XMLHTTPRequest」。它是一種支持異步請求的技術(shù)。XMLHTTPRequest使您可以使用JavaScript向服務器提出請求并處理響應,而不阻塞用戶。可以在頁面加載以后進行頁面的局部更新

「使用方法」

「1.實例化ajax對象」

「2. open()」 :創(chuàng)建HTTP請求 第一個參數(shù)是指定提交方式(post、get) 第二個參數(shù)是指定要提交的地址是哪 第三個參數(shù)是指定是異步還是同步(true表示異步,false表示同步) 第四和第五參數(shù)在HTTP認證的時候會用到。是可選的

「3.設(shè)置請求頭」

「setRequestHeader」(Stringheader,Stringvalue) 「(使用post方式才會使用到,get方法并不需要調(diào)用該方法)」

「4.發(fā)送請求」

「send(content)」 :發(fā)送請求給服務器 如果是get方式,并不需要填寫參數(shù),或填寫null 如果是post方式,把要提交的參數(shù)寫上去

「5. 注冊回調(diào)函數(shù)」

 /* 1.ajax: 在頁面不刷新的情況下向服務器請求數(shù)據(jù)
           2.XMLHttpRequest :http請求對象,負責實現(xiàn)ajax技術(shù)(小黃人)
                (1)創(chuàng)建XMLHttpRequest對象
                        * 小黃人,相當于黃袍加身的跑腿外賣小哥哥
                (2)設(shè)置請求
                        * 告訴小黃人服務器地址
                (3)發(fā)送請求
                        * 小黃人出發(fā)去指定地址取外賣(數(shù)據(jù))
                            * 2G網(wǎng)速:走路去的
                            * 3G網(wǎng)速:騎膜拜去的
                            * WIFI : 騎電動車去的
                            * 4G   : 騎小牛牌電動車去的
                (4)注冊回調(diào)函數(shù)
                        * 小黃人把取回的外賣送到你家門口
        
         */
//(1).實例化ajax對象
      let xhr = new XMLHttpRequest()
      //(2).設(shè)置請求方法和地址
      xhr.open("post", "http://www.liulongbin.top:3009/api/login")
      //(3).設(shè)置請求頭(post請求才需要設(shè)置)
      xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
      //(4).發(fā)送請求 : 參數(shù)格式  'key=value'
      xhr.send("username=admin&password=123456")
      //(5).注冊回調(diào)函數(shù)
      // xhr.onload = function() {};
      xhr.onreadystatechange = function() {
        //onreadystatechange會觸發(fā)多次,一般需要判斷xhr.readState == 4 才獲取響應數(shù)據(jù)
        if (xhr.readyState == 4) {
          console.log(xhr.responseText)
        }
      }

7.2. onreadstatechange事件
*/ 1. onload事件 :  接收服務器響應的數(shù)(一次請求,只會執(zhí)行一次)
  */      2. onreadystatechang事件 : 作用與onload事件一致(一次請求,會執(zhí)行多次)
  */          面試點:XMLHttpRequest對象的狀態(tài)碼 (xhr.readyState)
   */             0: 請求未建立  (創(chuàng)建了xhr對象,但是還沒調(diào)用open)
   */             1: 服務器連接已建立
   */             2. 請求已接收  (send之后,服務器已經(jīng)接收了請求)
   */             3. 請求處理中
   */             4. 請求已完成,且響應已就緒 ( 4狀態(tài)碼等同于onload事件 )
        
      //(1).實例化ajax對象
      let xhr = new XMLHttpRequest()
      console.log(xhr.readyState) //0
      //(2).設(shè)置請求方法和地址
      xhr.open("post", "http://www.liulongbin.top:3009/api/login")
        console.log(xhr.readyState) //1
      //(3).設(shè)置請求頭(post請求才需要設(shè)置)
      xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
      console.log(xhr.readyState) //1
      //(4).發(fā)送請求 : 參數(shù)格式  'key=value'
      xhr.send("username=admin&password=123456")
        console.log(xhr.readyState) //1
      //(5).注冊回調(diào)函數(shù)
      //a. onload 是新式瀏覽器才支持的
      //b. 如果要兼容更早的瀏覽器,可以使用 onreadystatechange
      //c. onreadystatechange觸發(fā)時機 :xhr.readState狀態(tài)變化
      // xhr.onload = function() {};

      xhr.onreadystatechange = function() {
        console.log(xhr.readyState) //2,3,4
        //onreadystatechange會觸發(fā)多次,一般需要判斷xhr.readState == 4 才獲取響應數(shù)據(jù)
        if (xhr.readyState == 4) {
          console.log(xhr.responseText)
        }
      }

7.3 如何上傳文件(上傳圖片)
   /*文件上傳思路總結(jié)
      1. 給file表單注冊onchange事件
        * 當用戶選擇圖片之后執(zhí)行
      2. 獲取用戶選擇的圖片
        * this.files[0]
      3. 創(chuàng)建FormData對象
        * 只有FormData才可以上傳文件
      4. 將圖片添加到FormData對象中
        * fd.append('參數(shù)名', this.files[0])
      5. 發(fā)送ajax請求
        * 文件上傳請求方法一定是post, 且請求參數(shù)為 FormData對象
      */
     
      //1. file類型表單自帶一個選擇文件點擊按鈕,當用戶選擇文件之后就會觸發(fā)onchange事件
      document.querySelector("#iptFile").onchange = function() {
        //this : file表單
        //(1)獲取用戶選擇的文件
        let file = this.files[0]
        // 非空判斷,如果內(nèi)容為undefined,給出提示
        if (file == undefined) {
          return alert("請選擇上傳文件!")
        }
        //(2)創(chuàng)建FormData對象, 只有FormData對象才可以上傳文件
        let fd = new FormData()
        //(3)添加文件
        fd.append("avatar", file)
        //(4)發(fā)送ajax請求, 參數(shù)為 FormData對象
        axios({
          method: "POST",
          url: "http://www.liulongbin.top:3009/api/upload/avatar",
          data: fd
        }).then(({ data: res }) => {
          console.log(res)
          if (res.code != 200) {
            return alert(res.message)
          }
          // 成功后提示,修改圖片路徑
          alert("恭喜您,上傳頭像成功!")
          document.querySelector("img").src = `http://www.liulongbin.top:3009${res.url}`
        })
      }

7.4 如何自定義上傳文件按鈕
//自定義文件上傳按鈕思路
//(1)隱藏file表單
//(2)給自定義按鈕添加一個點擊事件
//(3)點擊按鈕的時候,觸發(fā) file表單的點擊

document.querySelector('#btnChoose').onclick = function(){

//dom對象.onclick()  :  只能觸發(fā)你自己注冊的onclick事件,沒注冊觸發(fā)不了
//dom對象.click() : 模擬鼠標點擊。 觸發(fā)注冊的onclick事件 + 默認點擊事件
 
document.querySelector('#iptFile').click()
    
}
7.5 ajax請求如何取消
「1. 原生xhr取消請求」

var xhr = new XMLHttpRequest();
xhr.abort();
「2.axios取消請求」

「1.使用 CancelToken.source 工廠方法創(chuàng)建 cancel token」

const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/123', {
    cancelToken: source.token
}).catch(function(thrown) {
    if (axios.isCancel(thrown)) {
        console.log('Request canceled', thrown.message);
    } else {
    // 處理錯誤
    }
});

axios.post('/user/123', {
    name: '小明'
}, {
    cancelToken: source.token
})

// 取消請求(message 參數(shù)是可選的)
source.cancel('canceled by the user.');

「2.傳遞一個 executor 函數(shù)到 CancelToken 的構(gòu)造函數(shù)來創(chuàng)建 cancel token」

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函數(shù)接收一個 cancel 函數(shù)作為參數(shù)
    cancel = c;
  })
});

// cancel the request
cancel();

7.6取消ajax請求有什么意義
「取消ajax請求的意義」

已發(fā)出的請求可能仍然會到達后端
取消后續(xù)的回調(diào)處理,避免多余的回調(diào)處理,以及特殊情況,先發(fā)出的后返回,導致回調(diào)中的數(shù)據(jù)錯誤覆蓋
取消loading效果,以及該請求的其他交互效果,特別是在單頁應用中,A頁面跳轉(zhuǎn)到B頁面之后,A頁面的請求應該取消,否則回調(diào)中的一些處理可能影響B(tài)頁面
超時處理,錯誤處理等都省去了,節(jié)約資源
8. OPTIONS請求方法及使用場景
OPTIONS是除了GET和POST之外的其中一種 HTTP請求方法。(瀏覽器自動執(zhí)行)

OPTIONS方法是用于請求獲得由Request-URI標識的資源在請求/響應的通信過程中可以使用的功能選項。通過這個方法,客戶端可以「在采取具體資源請求之前,決定對該資源采取何種必要措施,或者了解服務器的性能」。該請求方法的響應不能緩存。

OPTIONS請求方法的「主要用途」有兩個:

獲取服務器支持的所有HTTP請求方法;
用來檢查訪問權(quán)限。例如:在進行 CORS 跨域資源共享時,對于復雜請求,就是使用 OPTIONS 方法發(fā)送「嗅探」請求,以判斷是否有對指定資源的訪問權(quán)限。
9. HTTP 1.0 和 HTTP 1.1 之間有哪些區(qū)別?
「連接方面」,http1.0 默認使用非持久連接,而 http1.1 默認使用持久連接。http1.1 通過使用持久連接來使多個 http 請求復用同一個 TCP 連接,以此來避免使用非持久連接時每次需要建立連接的時延。
「資源請求方面」,在 http1.0 中,存在一些浪費帶寬的現(xiàn)象,例如客戶端只是需要某個對象的一部分,而服務器卻將整個對象送過來了,并且不支持斷點續(xù)傳功能,http1.1 則在請求頭引入了 range 頭域,它允許只請求資源的某個部分,即返回碼是 206(Partial Content),這樣就方便了開發(fā)者自由的選擇以便于充分利用帶寬和連接。
「緩存方面」,在 http1.0 中主要使用 header 里的 If-Modified-Since、Expires 來做為緩存判斷的標準,http1.1 則引入了更多的緩存控制策略,例如 Etag、If-Unmodified-Since、If-Match、If-None-Match 等更多可供選擇的緩存頭來控制緩存策略。
「http1.1」 中「新增了 host 字段」,用來指定服務器的域名。http1.0 中認為每臺服務器都綁定一個唯一的 IP 地址,因此,請求消息中的 URL 并沒有傳遞主機名(hostname)。但隨著虛擬主機技術(shù)的發(fā)展,在一臺物理服務器上可以存在多個虛擬主機,并且它們共享一個IP地址。因此有了 host 字段,這樣就可以將請求發(fā)往到同一臺服務器上的不同網(wǎng)站。
http1.1 相對于 http1.0 還新增了很多「請求方法」,如 PUT、HEAD、OPTIONS 等。
10.HTTP 1.1 和 HTTP 2.0 的區(qū)別
「二進制協(xié)議」:HTTP/2 是一個二進制協(xié)議。在 HTTP/1.1 版中,報文的頭信息必須是文本(ASCII 編碼),數(shù)據(jù)體可以是文本,也可以是二進制。HTTP/2 則是一個徹底的二進制協(xié)議,頭信息和數(shù)據(jù)體都是二進制,并且統(tǒng)稱為"幀",可以分為頭信息幀和數(shù)據(jù)幀。幀的概念是它實現(xiàn)多路復用的基礎(chǔ)。
「多路復用:」 HTTP/2 實現(xiàn)了多路復用,HTTP/2 仍然復用 TCP 連接,但是在一個連接里,客戶端和服務器都可以同時發(fā)送多個請求或回應,而且不用按照順序一一發(fā)送,這樣就避免了"隊頭堵塞"【1】的問題。
「數(shù)據(jù)流:」 HTTP/2 使用了數(shù)據(jù)流的概念,因為 HTTP/2 的數(shù)據(jù)包是不按順序發(fā)送的,同一個連接里面連續(xù)的數(shù)據(jù)包,可能屬于不同的請求。因此,必須要對數(shù)據(jù)包做標記,指出它屬于哪個請求。HTTP/2 將每個請求或回應的所有數(shù)據(jù)包,稱為一個數(shù)據(jù)流。每個數(shù)據(jù)流都有一個獨一無二的編號。數(shù)據(jù)包發(fā)送時,都必須標記數(shù)據(jù)流 ID ,用來區(qū)分它屬于哪個數(shù)據(jù)流。
「頭信息壓縮:」 HTTP/2 實現(xiàn)了頭信息壓縮,由于 HTTP 1.1 協(xié)議不帶狀態(tài),每次請求都必須附上所有信息。所以,請求的很多字段都是重復的,比如 Cookie 和 User Agent ,一模一樣的內(nèi)容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。HTTP/2 對這一點做了優(yōu)化,引入了頭信息壓縮機制。一方面,頭信息使用 gzip 或 compress 壓縮后再發(fā)送;另一方面,客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,以后就不發(fā)送同樣字段了,只發(fā)送索引號,這樣就能提高速度了。
「服務器推送:」 HTTP/2 允許服務器未經(jīng)請求,主動向客戶端發(fā)送資源,這叫做服務器推送。使用服務器推送提前給客戶端推送必要的資源,這樣就可以相對減少一些延遲時間。這里需要注意的是 http2 下服務器主動推送的是靜態(tài)資源,和 WebSocket 以及使用 SSE 等方式向客戶端發(fā)送即時數(shù)據(jù)的推送是不同的。
11. 「什么是隊頭堵塞」
隊頭阻塞是由 HTTP 基本的“請求 - 應答”模型所導致的。HTTP 規(guī)定報文必須是“一發(fā)一收”,這就形成了一個先進先出的“串行”隊列。隊列里的請求是沒有優(yōu)先級的,只有入隊的先后順序,排在最前面的請求會被最優(yōu)先處理。如果隊首的請求因為處理的太慢耽誤了時間,那么隊列里后面的所有請求也不得不跟著一起等待,結(jié)果就是其他的請求承擔了不應有的時間成本,造成了隊頭堵塞的現(xiàn)象。

11.2 「隊頭阻塞的解決方案:」
(1)并發(fā)連接:對于一個域名允許分配多個長連接,那么相當于增加了任務隊列,不至于一個隊伍的任務阻塞其它所有任務。(2)域名分片:將域名分出很多二級域名,它們都指向同樣的一臺服務器,能夠并發(fā)的長連接數(shù)變多,解決了隊頭阻塞的問題。

12. HTTP和HTTPS協(xié)議的區(qū)別
HTTP和HTTPS協(xié)議的主要區(qū)別如下:

HTTPS協(xié)議需要CA證書,費用較高;而HTTP協(xié)議不需要;
HTTP協(xié)議是超文本傳輸協(xié)議,信息是明文傳輸?shù)模琀TTPS則是具有安全性的SSL加密傳輸協(xié)議;
使用不同的連接方式,端口也不同,HTTP協(xié)議端口是80,HTTPS協(xié)議端口是443;
HTTP協(xié)議連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是有SSL和HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認證的網(wǎng)絡(luò)協(xié)議,比HTTP更加安全。
13. GET方法URL長度限制的原因
實際上HTTP協(xié)議規(guī)范并沒有對get方法請求的url長度進行限制,這個限制是特定的「瀏覽器」及「服務器」對它的限制。IE對URL長度的限制是「2083」字節(jié)(2K+35)。由于IE瀏覽器對URL長度的允許值是「最小的」,所以開發(fā)過程中,只要URL不超過2083字節(jié),那么在所有瀏覽器中工作都不會有問題。

GET的長度值 = URL(2083)- (你的Domain+Path)-2(2是get請求中?=兩個字符的長度)

下面看一下主流瀏覽器對get方法中url的長度限制范圍:

Microsoft Internet Explorer (Browser):IE瀏覽器對URL的最大限制為「2083」個字符,如果超過這個數(shù)字,提交按鈕沒有任何反應。
Firefox (Browser):對于Firefox瀏覽器URL的長度限制為 「65,536」 個字符。
Safari (Browser):URL最大長度限制為 「80,000」 個字符。
Opera (Browser):URL最大長度限制為 「190,000」 個字符。
Google (chrome):URL最大長度限制為 「8182」 個字符。
主流的服務器對get方法中url的長度限制范圍:

Apache (Server):能接受最大url長度為「8192」個字符。
Microsoft Internet Information Server(IIS):能接受最大url的長度為「16384」個字符。
根據(jù)上面的數(shù)據(jù),可以知道,get方法中的URL長度最長不超過2083個字符,這樣所有的瀏覽器和服務器都可能正常工作。

14.一個頁面從輸入 URL 到頁面加載顯示完成,這個過程中都發(fā)生了什么?
(1)「解析URL:」 「首先會對 URL 進行解析,分析所需要使用的傳輸協(xié)議和請求的資源的路徑」。如果輸入的 URL 中的協(xié)議或者主機名不合法,將會把地址欄中輸入的內(nèi)容傳遞給搜索引擎。如果沒有問題,瀏覽器會檢查 URL 中是否出現(xiàn)了非法字符,如果存在非法字符,則對非法字符進行轉(zhuǎn)義后再進行下一過程。

(2)「緩存判斷:」 「瀏覽器會判斷所請求的資源是否在緩存里」,如果請求的資源在緩存里并且沒有失效,那么就直接使用,否則向服務器發(fā)起新的請求。

(3)「DNS解析:」 下一步首先需要獲取的是輸入的 URL 中的域名的 IP 地址,首先會「判斷本地是否有該域名的 IP 地址的緩存」,如果有則使用,「如果沒有則向本地 DNS 服務器發(fā)起請求」。「本地 DNS 服務器也會先檢查是否存在緩存」,如果「沒有就會先向根域名服務器發(fā)起請求」,獲得負責的頂級域名服務器的地址后,「再向頂級域名服務器請求」,然后獲得負責的權(quán)威域名服務器的地址后,「再向權(quán)威域名服務器發(fā)起請求」,「最終獲得域名的 IP 地址后,本地 DNS 服務器再將這個 IP 地址返回給請求的用戶」。用戶向本地 DNS 服務器發(fā)起請求屬于遞歸請求,本地 DNS 服務器向各級域名服務器發(fā)起請求屬于迭代請求。

(4)「獲取MAC地址(選說)」 當瀏覽器得到 IP 地址后,「數(shù)據(jù)傳輸還需要知道目的主機 MAC 地址」,因為應用層下發(fā)數(shù)據(jù)給傳輸層,TCP 協(xié)議會指定源端口號和目的端口號,然后下發(fā)給網(wǎng)絡(luò)層。網(wǎng)絡(luò)層會將本機地址作為源地址,獲取的 IP 地址作為目的地址。然后將下發(fā)給數(shù)據(jù)鏈路層,數(shù)據(jù)鏈路層的發(fā)送需要加入通信雙方的 MAC 地址,本機的 MAC 地址作為源 MAC 地址,目的 MAC 地址需要分情況處理。通過將 IP 地址與本機的子網(wǎng)掩碼相與,可以判斷是否與請求主機在同一個子網(wǎng)里,如果在同一個子網(wǎng)里,可以使用 APR 協(xié)議獲取到目的主機的 MAC 地址,如果不在一個子網(wǎng)里,那么請求應該轉(zhuǎn)發(fā)給網(wǎng)關(guān),由它代為轉(zhuǎn)發(fā),此時同樣可以通過 ARP 協(xié)議來獲取網(wǎng)關(guān)的 MAC 地址,此時目的主機的 MAC 地址應該為網(wǎng)關(guān)的地址。

(5)「TCP三次握手:」 ,「確認客戶端與服務器的接收與發(fā)送能力」,下面是 TCP 建立連接的三次握手的過程,首先客戶端向服務器發(fā)送一個 SYN 連接請求報文段和一個隨機序號,服務端接收到請求后向服務器端發(fā)送一個 SYN ACK報文段,確認連接請求,并且也向客戶端發(fā)送一個隨機序號??蛻舳私邮辗掌鞯拇_認應答后,進入連接建立的狀態(tài),同時向服務器也發(fā)送一個ACK 確認報文段,服務器端接收到確認后,也進入連接建立狀態(tài),此時雙方的連接就建立起來了。

(6)「HTTPS握手(選說):」 「如果使用的是 HTTPS 協(xié)議,在通信前還存在 TLS 的一個四次握手的過程」。首先由客戶端向服務器端發(fā)送使用的協(xié)議的版本號、一個隨機數(shù)和可以使用的加密方法。服務器端收到后,確認加密的方法,也向客戶端發(fā)送一個隨機數(shù)和自己的數(shù)字證書??蛻舳耸盏胶螅紫葯z查數(shù)字證書是否有效,如果有效,則再生成一個隨機數(shù),并使用證書中的公鑰對隨機數(shù)加密,然后發(fā)送給服務器端,并且還會提供一個前面所有內(nèi)容的 hash 值供服務器端檢驗。服務器端接收后,使用自己的私鑰對數(shù)據(jù)解密,同時向客戶端發(fā)送一個前面所有內(nèi)容的 hash 值供客戶端檢驗。這個時候雙方都有了三個隨機數(shù),按照之前所約定的加密方法,使用這三個隨機數(shù)生成一把秘鑰,以后雙方通信前,就使用這個秘鑰對數(shù)據(jù)進行加密后再傳輸。

(7)「發(fā)送HTTP請求」

「服務器處理請求,返回HTTP報文」(響應)(文件)

(8)「頁面渲染:」 瀏覽器首先會根據(jù) html 文件(響應) 「建 DOM 樹」,根據(jù)解析到的 css 文件構(gòu)「建 CSSOM 樹」,如果遇到 script 標簽,則判端是否含有 defer 或者 async 屬性,要不然 script 的加載和執(zhí)行會造成頁面的渲染的阻塞?!府?DOM 樹和 CSSOM 樹建立好后,根據(jù)它們來構(gòu)建渲染樹」。渲染樹構(gòu)建好后,會根據(jù)渲染樹來進行布局。布局完成后,最后使用瀏覽器的 UI 接口對頁面進行繪制。這個時候整個頁面就顯示出來了。

(9)「TCP四次揮手:」 「最后一步是 TCP 斷開連接的四次揮手過程」。若客戶端認為數(shù)據(jù)發(fā)送完成,則它需要向服務端發(fā)送連接釋放請求。服務端收到連接釋放請求后,會告訴應用層要釋放 TCP 鏈接。然后會發(fā)送 ACK 包,并進入 CLOSE_WAIT 狀態(tài),此時表明客戶端到服務端的連接已經(jīng)釋放,不再接收客戶端發(fā)的數(shù)據(jù)了。但是因為 TCP 連接是雙向的,所以服務端仍舊可以發(fā)送數(shù)據(jù)給客戶端。服務端如果此時還有沒發(fā)完的數(shù)據(jù)會繼續(xù)發(fā)送,完畢后會向客戶端發(fā)送連接釋放請求,然后服務端便進入 LAST-ACK 狀態(tài)??蛻舳耸盏结尫耪埱蠛螅蚍斩税l(fā)送確認應答,此時客戶端進入 TIME-WAIT 狀態(tài)。該狀態(tài)會持續(xù) 2MSL(最大段生存期,指報文段在網(wǎng)絡(luò)中生存的時間,超時會被拋棄) 時間,若該時間段內(nèi)沒有服務端的重發(fā)請求的話,就進入 CLOSED 狀態(tài)。當服務端收到確認應答后,也便進入 CLOSED 狀態(tài)。

15.頁面有多張圖片,HTTP是怎樣的加載表現(xiàn)?
在HTTP 1下,瀏覽器對一個域名下最大TCP連接數(shù)為6,所以會請求多次。可以用「多域名部署」解決。這樣可以提高同時請求的數(shù)目,加快頁面圖片的獲取速度。

在HTTP 2下,可以一瞬間加載出來很多資源,因為,HTTP2支持多路復用,可以在一個TCP連接中發(fā)送多個HTTP請求。

16. HTTP2的頭部壓縮算法是怎樣的?
HTTP2的頭部壓縮是HPACK算法。在客戶端和服務器兩端建立“字典”,用索引號表示重復的字符串,采用哈夫曼編碼來壓縮整數(shù)和字符串,可以達到50%~90%的高壓縮率。

具體來說:

在客戶端和服務器端使用“首部表”來跟蹤和存儲之前發(fā)送的鍵值對,對于相同的數(shù)據(jù),不再通過每次請求和響應發(fā)送;
首部表在HTTP/2的連接存續(xù)期內(nèi)始終存在,由客戶端和服務器共同漸進地更新;
每個新的首部鍵值對要么被追加到當前表的末尾,要么替換表中之前的值。
17. HTTP請求報文的是什么樣的?
請求報?有4部分組成:

請求?
請求頭部
空?
請求體
「其中:」

(1)請求?包括:請求?法字段、URL字段、HTTP協(xié)議版本字段。它們?空格分隔。例如,GET /index.html HTTP/1.1。

(2)請求頭部:請求頭部由關(guān)鍵字/值對組成,每??對,關(guān)鍵字和值?英?冒號“:”分隔

User-Agent:產(chǎn)?請求的瀏覽器類型。
Accept:客戶端可識別的內(nèi)容類型列表。
Host:請求的主機名,允許多個域名同處?個IP地址,即虛擬主機。
(3)請求體: post put等請求攜帶的數(shù)據(jù)

18. HTTP響應報文的是什么樣的?
請求報?有4部分組成:

響應?:由網(wǎng)絡(luò)協(xié)議版本,狀態(tài)碼和狀態(tài)碼的原因短語組成,例如 HTTP/1.1 200 OK
響應頭:響應部?組成
空?
響應體:服務器響應的數(shù)據(jù)






19. HTTP協(xié)議的優(yōu)點和缺點
HTTP 是超文本傳輸協(xié)議,它定義了客戶端和服務器之間交換報文的格式和方式,默認使用 80 端口。它使用 TCP 作為傳輸層協(xié)議,保證了數(shù)據(jù)傳輸?shù)目煽啃浴?br>
HTTP協(xié)議具有以下「優(yōu)點」:

支持客戶端/服務器模式
「簡單快速」:客戶向服務器請求服務時,只需傳送請求方法和路徑。由于 HTTP 協(xié)議簡單,使得 HTTP 服務器的程序規(guī)模小,因而通信速度很快。
「無連接」:無連接就是限制每次連接只處理一個請求。服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接,采用這種方式可以節(jié)省傳輸時間。
「無狀態(tài)」:HTTP 協(xié)議是無狀態(tài)協(xié)議,這里的狀態(tài)是指通信過程的上下文信息。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能會導致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務器不需要先前信息時它的應答就比較快。
「靈活」:HTTP 允許傳輸任意類型的數(shù)據(jù)對象。正在傳輸?shù)念愋陀?Content-Type 加以標記。
HTTP協(xié)議具有以下「缺點」:

「無狀態(tài):」 HTTP 是一個無狀態(tài)的協(xié)議,HTTP 服務器不會保存關(guān)于客戶的任何信息。
「明文傳輸:」 協(xié)議中的報文使用的是文本形式,這就直接暴露給外界,不安全。
「不安全」
(1)通信使用明文(不加密),內(nèi)容可能會被竊聽;(2)不驗證通信方的身份,因此有可能遭遇偽裝;(3)無法證明報文的完整性,所以有可能已遭篡改;

20. 說一下HTTP 3.0
HTTP3.0,也稱作HTTP over QUIC。HTTP3.0的核心是QUIC(讀音quick)協(xié)議,由Google在 2015年提出的SPDY v3演化而來的新協(xié)議,傳統(tǒng)的HTTP協(xié)議是基于傳輸層TCP的協(xié)議,而QUIC是基于傳輸層UDP上的協(xié)議,可以定義成:HTTP3.0基于UDP的安全可靠的HTTP2.0協(xié)議。

21. HTTP的兩種連接模式
HTTP 協(xié)議是基于 TCP/IP,并且使用了「請求-應答」的通信模式。

「HTTP協(xié)議有兩種連接模式,一種是持續(xù)連接,一種非持續(xù)連接」。(1)非持續(xù)連接指的是服務器必須為每一個請求的對象建立和維護一個全新的連接。(2)持續(xù)連接下,TCP 連接默認不關(guān)閉,可以被多個請求復用。采用持續(xù)連接的好處是可以避免每次建立 TCP 連接三次握手時所花費的時間。

22. URL有哪些組成部分
以下面的URL為例www.aspxfans.com:8080/news/index?ID=246188#name

從上面的URL可以看出,一個完整的URL包括以下幾部分:

「協(xié)議部分」:該URL的協(xié)議部分為“http:”,這代表網(wǎng)頁使用的是HTTP協(xié)議。在Internet中可以使用多種協(xié)議,如HTTP,F(xiàn)TP等等本例中使用的是HTTP協(xié)議。在"HTTP"后面的“//”為分隔符;
「域名部分」:該URL的域名部分為www.aspxfans.com。一個URL中,也可以使用IP地址作為域名使用
「端口部分」:跟在域名后面的是端口,域名和端口之間使用“:”作為分隔符。端口不是一個URL必須的部分,如果省略端口部分,將采用默認端口(HTTP協(xié)議默認端口是80,HTTPS協(xié)議默認端口是443);
「虛擬目錄部分」:從域名后的第一個“/”開始到最后一個“/”為止,是虛擬目錄部分。虛擬目錄也不是一個URL必須的部分。本例中的虛擬目錄是“/news/”;
「文件名部分」:從域名后的最后一個“/”開始到“?”為止,是文件名部分,如果沒有“?”,則是從域名后的最后一個“/”開始到“#”為止,是文件部分,如果沒有“?”和“#”,那么從域名后的最后一個“/”開始到結(jié)束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一個URL必須的部分,如果省略該部分,則使用默認的文件名;
「錨部分」:從“#”開始到最后,都是錨部分。本例中的錨部分是“name”。錨部分也不是一個URL必須的部分;
「參數(shù)部分」:從“?”開始到“#”為止之間的部分為參數(shù)部分,又稱搜索部分、查詢部分。本例中的參數(shù)部分為“boardID=5&ID=24618&page=1”。參數(shù)可以允許有多個參數(shù),參數(shù)與參數(shù)之間用“&”作為分隔符。
23.與緩存相關(guān)的HTTP請求頭有哪些
強緩存:

Expires
Cache-Control
協(xié)商緩存:

Etag、If-None-Match
Last-Modified、If-Modified-Since
24. 強緩存和協(xié)商緩存
「1.強緩存:」 不會向服務器發(fā)送請求,直接從緩存中讀取資源,在chrome控制臺的Network選項中可以看到該請求返回200的狀態(tài)碼,并且size顯示from disk cache或from memory cache兩種(灰色表示緩存)。

「2.協(xié)商緩存:」 向服務器發(fā)送請求,服務器會根據(jù)這個請求的request header的一些參數(shù)來判斷是否命中協(xié)商緩存,如果命中,則返回304狀態(tài)碼并帶上新的response header通知瀏覽器從緩存中讀取資源;

共同點:都是從客戶端緩存中讀取資源;區(qū)別是強緩存不會發(fā)請求,協(xié)商緩存會發(fā)請求。

25. HTTP的keep-alive有什么作用?
「http1.0默認關(guān)閉,需要手動開啟。http1.1后默認開啟」

「作用:」 使客戶端到服務器端的鏈接持續(xù)有效(「長連接」),當出現(xiàn)對服務器的后續(xù)請求時,keep-Alive功能避免了建立或者重新建立鏈接。

「使用方法:」 在請求頭中加上Connection:keep-alive。

「優(yōu)點:」

較少的CPU和內(nèi)存的占用(因為要打開的連接數(shù)變少了,復用了連接)
減少了后續(xù)請求的延遲(無需再進行握手)
「缺點:」 本來可以釋放的資源仍舊被占用。有的請求已經(jīng)結(jié)束了,但是還一直連接著。

「解決方法:」 服務器設(shè)置過期時間和請求次數(shù),超過這個時間或者次數(shù)就斷掉連接。

26. OSI的七層模型是什么?
ISO于1978年開發(fā)的一套標準架構(gòu)ISO模型,被引用來說明數(shù)據(jù)通信協(xié)議的結(jié)構(gòu)和功能。

OSI在功能上可以劃分為兩組:

網(wǎng)絡(luò)群組:物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層

使用者群組:傳輸層、會話層、表示層、應用層

OSI七層網(wǎng)絡(luò)模型    TCP/IP四層概念模型    對應網(wǎng)絡(luò)協(xié)議
7:應用層    應用層    HTTP、RTSP TFTP(簡單文本傳輸協(xié)議)、FTP、 NFS(數(shù)域篩法,數(shù)據(jù)加密)、WAIS`(廣域信息查詢系統(tǒng))
6:表示層    應用層    Telnet(internet遠程登陸服務的標準協(xié)議)、Rlogin、SNMP(網(wǎng)絡(luò)管理協(xié)議)、Gopher
5:會話層    應用層    SMTP(簡單郵件傳輸協(xié)議)、DNS(域名系統(tǒng))
4:傳輸層    傳輸層    TCP(傳輸控制協(xié)議)、UDP(用戶數(shù)據(jù)報協(xié)議))
3:網(wǎng)絡(luò)層    網(wǎng)際層    ARP(地域解析協(xié)議)、RARP、AKP、UUCP(Unix to Unix copy)
2:數(shù)據(jù)鏈路層    數(shù)據(jù)鏈路層    FDDI(光纖分布式數(shù)據(jù)接口)、Ethernet、Arpanet、PDN(公用數(shù)據(jù)網(wǎng))、SLIP(串行線路網(wǎng)際協(xié)議)PPP(點對點協(xié)議,通過撥號或?qū)>€方建立點對點連接發(fā)送數(shù)據(jù))
1:物理層    物理層    SMTP(簡單郵件傳輸協(xié)議)、DNS(域名系統(tǒng))
其中高層(7、6、5、4層)定義了應用程序的功能,下面三層(3、2、1層)主要面向通過網(wǎng)絡(luò)的端到端的數(shù)據(jù)流

二、HTTPS
1. 什么是HTTPS協(xié)議?
超文本傳輸安全協(xié)議(Hypertext Transfer Protocol Secure,簡稱:HTTPS)是一種通過計算機網(wǎng)絡(luò)進行安全通信的傳輸協(xié)議。「HTTPS經(jīng)由HTTP進行通信,利用SSL/TLS來加密數(shù)據(jù)包?!?HTTPS的主要目的是提供對網(wǎng)站服務器的身份認證,保護交換數(shù)據(jù)的隱私與完整性。HTTP協(xié)議采用「明文傳輸」信息,存在「信息竊聽」、「信息篡改」和「信息劫持」的風險,而協(xié)議TLS/SSL具有「身份驗證」、「信息加密」和「完整性校驗」的功能,可以避免此類問題發(fā)生。

安全層的主要職責就是「對發(fā)起的HTTP請求的數(shù)據(jù)進行加密操作」 和 「對接收到的HTTP的內(nèi)容進行解密操作」。

2. TLS/SSL的工作原理
「TLS」全稱「安全傳輸層協(xié)議」(Transport Layer Security)及其前身「安全套接層」(Secure Sockets Layer,縮寫作「SSL」) 是介于TCP和HTTP之間的一層安全協(xié)議,不影響原有的TCP協(xié)議和HTTP協(xié)議,所以使用HTTPS基本上不需要對HTTP頁面進行太多的改造。

TLS/SSL的功能實現(xiàn)主要依賴三類基本算法:「散列函數(shù)hash」、「對稱加密」、「非對稱加密」。這三類算法的作用如下:

散列算法用來驗證信息的完整性
對稱加密算法采用協(xié)商的秘鑰對數(shù)據(jù)加密
非對稱加密實現(xiàn)身份認證和秘鑰協(xié)商

3. 對稱加密、非對稱加密是什么,有什么區(qū)別?
「對稱加密和非對稱加密是安全傳輸層里的加密算法」

「對稱加密」

對稱加密的特點是文件加密和解密使用相同的密鑰,即加密密鑰也可以用作解密密鑰,

這種方法在密碼學中叫做對稱加密算法,對稱加密算法使用起來簡單快捷,密鑰較短,且破譯困難

「通信的雙?都使?同?個秘鑰進?加密, 解密。」 ?如,兩個人事先約定的暗號,就屬于對稱加密。

「優(yōu)點:」

計算量小、加密速度快、加密效率高。

「缺點:」

「在數(shù)據(jù)傳送前,發(fā)送方和接收方必須商定好秘鑰,然后雙方保存好秘鑰?!?br>
「如果一方的秘鑰被泄露,那么加密信息也就不安全了」

最不安全的地方, 就在于第一開始, 互相約定密鑰的時候!!! 傳遞密鑰!

使用場景:本地數(shù)據(jù)加密、https 通信、網(wǎng)絡(luò)傳輸?shù)?br>
「非對稱加密」

通信的雙方使用不同的秘鑰進行加密解密,即秘鑰對(私鑰 + 公鑰)。

特征: 私鑰可以解密公鑰加密的內(nèi)容, 公鑰可以解密私鑰加密的內(nèi)容

非對稱加密的特點是:

優(yōu)點:非對稱加密與對稱加密相比其安全性更好
「缺點:加密和解密花費時間長、速度慢,只適合對少量數(shù)據(jù)進行加密?!?br>使用場景:https 會話前期、CA 數(shù)字證書、信息加密、登錄認證等

4. 數(shù)字證書是什么?
使用一種 Hash 算法來對公鑰和其他信息進行加密,生成一個信息摘要,然后讓有公信力的認證中心(簡稱 CA )用它的私鑰對消息摘要加密,形成簽名。最后將原始的信息和簽名合在一起,稱為「數(shù)字證書」。當接收方收到數(shù)字證書的時候,先根據(jù)原始信息使用同樣的 Hash 算法生成一個摘要,然后使用公證處的公鑰來對數(shù)字證書中的摘要進行解密,最后將解密的摘要和生成的摘要進行對比,就能發(fā)現(xiàn)得到的信息是否被更改了。

4.2 數(shù)字證書的作用
現(xiàn)在的方法也不一定是安全的,因為沒有辦法確定得到的公鑰就一定是安全的公鑰??赡艽嬖谝粋€中間人,截取了對方發(fā)給我們的公鑰,然后將他自己的公鑰發(fā)送給我們,當我們使用他的公鑰加密后發(fā)送的信息,就可以被他用自己的私鑰解密。然后他偽裝成我們以同樣的方法向?qū)Ψ桨l(fā)送信息,這樣我們的信息就被竊取了,然而自己還不知道。為了解決這樣的問題,可以使用「數(shù)字證書」。

4.3 數(shù)字簽名是什么?
數(shù)字簽名就是先用CA自帶的Hash算法來計算出證書內(nèi)容的一個摘要,然后使用CA私鑰進行加密,組成數(shù)字簽名。

當別人把他的數(shù)字證書發(fā)過來時,接收方用同樣的算法再次生成摘要,用CA公鑰解密后得到CA生成的摘要,兩者進行對比后,就能確定中間是否被人篡改。這樣就能最大程度的保證通信的安全了。






5. HTTPS通信(握手)過程
HTTPS的通信過程如下:

客戶端向服務器發(fā)起請求,請求中包含使用的協(xié)議版本號、生成的一個隨機數(shù)、以及客戶端支持的加密方法。
服務器端接收到請求后,確認雙方使用的加密方法、并給出服務器的證書、以及一個服務器生成的隨機數(shù)。
客戶端確認服務器證書有效后,生成一個新的隨機數(shù),并使用數(shù)字證書中的公鑰,加密這個隨機數(shù),然后發(fā)給服 務器。并且還會提供一個前面所有內(nèi)容的 hash 的值,用來供服務器檢驗。
服務器使用自己的私鑰,來解密客戶端發(fā)送過來的隨機數(shù)。并提供前面所有內(nèi)容的 hash 值來供客戶端檢驗。
客戶端和服務器端根據(jù)約定的加密方法使用前面的三個隨機數(shù),生成對話秘鑰,以后的對話過程都使用這個秘鑰來加密信息。
6. HTTPS的優(yōu)缺點
HTTPS的「優(yōu)點」如下:

使用HTTPS協(xié)議可以認證用戶和服務器,確保數(shù)據(jù)發(fā)送到正確的客戶端和服務器;
使用HTTPS協(xié)議可以進行加密傳輸、身份認證,通信更加安全,防止數(shù)據(jù)在傳輸過程中被竊取、修改,確保數(shù)據(jù)安全性;
HTTPS是現(xiàn)行架構(gòu)下最安全的解決方案,雖然不是絕對的安全,但是大幅增加了中間人攻擊的成本;
HTTPS的「缺點」如下:

HTTPS需要做服務器和客戶端雙方的加密個解密處理,耗費更多服務器資源,過程復雜;
HTTPS協(xié)議握手階段比較費時,增加頁面的加載時間;
SSL證書是收費的,功能越強大的證書費用越高;
HTTPS連接服務器端資源占用高很多,支持訪客稍多的網(wǎng)站需要投入更大的成本;
SSL證書需要綁定IP,不能再同一個IP上綁定多個域名。
7. 「HTTPS」是如何保證安全的?
結(jié)合「對稱加密」和「非對稱加密」兩種加密?式,將對稱加密的密鑰使??對稱加密的公鑰進?加密,然后發(fā)送出去,接收?使?私鑰進?解密得到對稱加密的密鑰,然后雙?可以使?對稱加密來進?溝通。

這個時候還需要?個安全的「第三?頒發(fā)證書」(CA),證明身份的身份,防?被中間?攻擊。

為了防止中間人篡改證書,需要用到「數(shù)字簽名」這個技術(shù)

數(shù)字簽名就是?CA?帶的HASH算法對證書的內(nèi)容進?HASH得到?個摘要,再?CA的私鑰加密,最終組成數(shù)字簽名。當別?把他的證書發(fā)過來的時候,我再?同樣的Hash算法,再次?成消息摘要,然后?CA的公鑰對數(shù)字簽名解密,得到CA創(chuàng)建的消息摘要,兩者??,就知道中間有沒有被?篡改了。這個時候就能最?程度保證通信的安全了。

8.HTTP狀態(tài)碼分別代表什么意思?
「類別」    「原因」    「描述」
1xx    Informational(信息性狀態(tài)碼)    接受的請求正在處理
2xx    Success(成功狀態(tài)碼)    請求正常處理完畢
3xx    Redirection(重定向狀態(tài)碼)    需要進行附加操作一完成請求
4xx    Client Error (客戶端錯誤狀態(tài)碼)    服務器無法處理請求
5xx    Server Error(服務器錯誤狀態(tài)碼)    服務器處理請求出錯
「(1)2XX 成功」

200 OK,表示從客戶端發(fā)來的請求在服務器端被正確處理
201 Created 請求已經(jīng)被實現(xiàn),而且有一個新的資源已經(jīng)依據(jù)請求的需要而建立。通常是在POST請求,或者是某些PUT請求之后創(chuàng)建了內(nèi)容,進行的返回的響應。
202 Accepted 請求服務器已接受,但是尚未處理,不保證完成請求。適合異步任務或者說需要處理時間比較長的請求,避免HTTP鏈接一直占用。
204 No content,表示請求成功,但響應報文不含實體的主體部分
205 Reset Content,表示請求成功,但響應報文不含實體的主體部分,但是與 204 響應不同在于要求請求方重置內(nèi)容
206 Partial Content,進行的是范圍請求,表示服務器已經(jīng)成功處理了部分GET請求,響應頭中會包含獲取的內(nèi)容范圍(常用于分段下載)
「(2)3XX 重定向」

301 moved permanently,永久性重定向,表示資源已被分配了新的 URL
302 found,臨時性重定向,表示資源臨時被分配了新的 URL,支持搜索引擎優(yōu)化
303 see other,表示資源存在著另一個 URL,應使用 GET 方法獲取資源
304 not modified,自從上次請求后,請求的網(wǎng)頁內(nèi)容未修改過。服務器返回此響應時,不會返回網(wǎng)頁內(nèi)容。(「協(xié)商緩存」)
307 temporary redirect,臨時重定向,和302含義類似,但是期望客戶端保持請求方法不變向新的地址發(fā)出請求
「(3)4XX 客戶端錯誤」

400 bad request,請求報文存在語法錯誤(傳參格式不正確)
401 unauthorized,表示發(fā)送的請求需要有通過 HTTP 認證的認證信息(沒有權(quán)限)
403 forbidden,表示對請求資源的訪問被服務器拒絕
404 not found,表示在服務器上沒有找到請求的資源
408 Request Timeout 客戶端請求超時
409 Confict 請求的資源可能引起沖突
「(4)5XX 服務器錯誤」

500 internal sever error,表示服務器端在執(zhí)行請求時發(fā)生了錯誤
501 Not Implemented,表示服務器不支持當前請求所需要的某個功能
503 service unavailable,表明服務器暫時處于超負載或正在停機維護,無法處理請求
9. 同樣是重定向,「307」,「303」,「302」的區(qū)別?
「302」是http1.0的協(xié)議狀態(tài)碼,在http1.1版本的時候為了細化302狀態(tài)碼?出來了兩個303和307。

「303」明確表示客戶端應當采?get?法獲取資源,他會把POST請求變?yōu)镚ET請求進?重定向。

「307」會遵照瀏覽器標準,不會從post變?yōu)間et。

10. DNS 協(xié)議是什么
「概念」:DNS 是「域名系統(tǒng)」 (Domain Name System) 的縮寫,提供的是一種主機名到 IP 地址的轉(zhuǎn)換服務,就是我們常說的域名系統(tǒng)。它是一個由分層的 DNS 服務器組成的分布式數(shù)據(jù)庫,是定義了主機如何查詢這個分布式數(shù)據(jù)庫的方式的應用層協(xié)議。能夠使人更方便的訪問互聯(lián)網(wǎng),而不用去記住能夠被機器直接讀取的IP數(shù)串。

「作用」:將域名解析為IP地址,客戶端向DNS服務器(DNS服務器有自己的IP地址)發(fā)送域名查詢請求,DNS服務器告知客戶機Web服務器的 IP 地址。

11. DNS完整的查詢過程
DNS服務器解析域名的過程:

首先會在「瀏覽器的緩存」中查找對應的IP地址,如果查找到直接返回,若找不到繼續(xù)下一步
將請求發(fā)送給「本地DNS服務器」,在本地域名服務器緩存中查詢,如果查找到,就直接將查找結(jié)果返回,若找不到繼續(xù)下一步
本地DNS服務器向「根域名服務器」發(fā)送請求,根域名服務器會返回一個所查詢域的頂級域名服務器地址
本地DNS服務器向「頂級域名服務器」發(fā)送請求,接受請求的服務器查詢自己的緩存,如果有記錄,就返回查詢結(jié)果,如果沒有就返回相關(guān)的下一級的權(quán)威域名服務器的地址
本地DNS服務器向「權(quán)威域名服務器」發(fā)送請求,域名服務器返回對應的結(jié)果
本地DNS服務器將返回結(jié)果保存在緩存中,便于下次使用
本地DNS服務器將返回結(jié)果返回給瀏覽器
12. 簡述一下TCP的三次握手
「第一次握手:」 客戶端向服務端發(fā)送連接請求報文段。該報文段中包含自身的數(shù)據(jù)通訊初始序號。請求發(fā)送后,客戶端便進入 SYN-SENT 狀態(tài)。

「第二次握手:」 服務端收到連接請求報文段后,如果同意連接,則會發(fā)送一個應答,該應答中也會包含自身的數(shù)據(jù)通訊初始序號,發(fā)送完成后便進入 SYN-RECEIVED 狀態(tài)。

「第三次握手:」 當客戶端收到連接同意的應答后,還要向服務端發(fā)送一個確認報文。客戶端發(fā)完這個報文段后便進入 ESTABLISHED 狀態(tài),服務端收到這個應答后也進入 ESTABLISHED 狀態(tài),此時連接建立成功。

13. 「TCP什么要三次握手呢?兩次不行嗎?」
為了確認雙方的接收能力和發(fā)送能力都正常
如果是用兩次握手,則會出現(xiàn)下面這種情況:
如客戶端發(fā)出連接請求,但因連接請求報文丟失而未收到確認,于是客戶端再重傳一次連接請求。后來收到了確認,建立了連接。數(shù)據(jù)傳輸完畢后,就釋放了連接,客戶端共發(fā)出了兩個連接請求報文段,其中第一個丟失,第二個到達了服務端,但是第一個丟失的報文段只是在某些網(wǎng)絡(luò)結(jié)點長時間滯留了,延誤到連接釋放以后的某個時間才到達服務端,此時服務端誤認為客戶端又發(fā)出一次新的連接請求,于是就向客戶端發(fā)出確認報文段,同意建立連接,不采用三次握手,只要服務端發(fā)出確認,就建立新的連接了,此時客戶端忽略服務端發(fā)來的確認,也不發(fā)送數(shù)據(jù),則服務端一致等待客戶端發(fā)送數(shù)據(jù),浪費資源。

14. 簡述一下TCP的四次揮手
「第一次揮手:」 若客戶端認為數(shù)據(jù)發(fā)送完成,則它需要向服務端發(fā)送連接釋放請求。

「第二次揮手」:服務端收到連接釋放請求后,會告訴應用層要釋放 TCP 鏈接。然后會發(fā)送 ACK 包,并進入 CLOSE_WAIT 狀態(tài),此時表明客戶端到服務端的連接已經(jīng)釋放,不再接收客戶端發(fā)的數(shù)據(jù)了。但是因為 TCP 連接是雙向的,所以服務端仍舊可以發(fā)送數(shù)據(jù)給客戶端。

「第三次揮手」:服務端如果此時還有沒發(fā)完的數(shù)據(jù)會繼續(xù)發(fā)送,完畢后會向客戶端發(fā)送連接釋放請求,然后服務端便進入 LAST-ACK 狀態(tài)。

「第四次揮手:」 客戶端收到釋放請求后,向服務端發(fā)送確認應答,此時客戶端進入 TIME-WAIT 狀態(tài)。該狀態(tài)會持續(xù) 2MSL(最大段生存期,指報文段在網(wǎng)絡(luò)中生存的時間,超時會被拋棄) 時間,若該時間段內(nèi)沒有服務端的重發(fā)請求的話,就進入 CLOSED 狀態(tài)。當服務端收到確認應答后,也便進入 CLOSED 狀態(tài)。

15. TCP「為什么需要四次揮手呢?」
因為當服務端收到客戶端的SYN連接請求報文后,可以直接發(fā)送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關(guān)閉連接時,當服務端收到FIN報文時,很可能并不會立即關(guān)閉SOCKET,所以只能先回復一個ACK報文,告訴客戶端,“你發(fā)的FIN報文我收到了”。只有等到我服務端所有的報文都發(fā)送完了,我才能發(fā)送FIN報文,因此不能一起發(fā)送,故需要四次揮手。

16. TCP粘包是怎么回事,如何處理?
默認情況下, TCP 連接會啟?「延遲傳送算法」 (Nagle 算法), 在數(shù)據(jù)發(fā)送之前緩存他們. 如果短時間有多個數(shù)據(jù)發(fā)送, 會緩沖到?起作?次發(fā)送 (緩沖??? socket.bufferSize ), 這樣可以減少 IO 消耗提?性能.

如果是傳輸?件的話, 那么根本不?處理粘包的問題, 來?個包拼?個包就好了。但是如果是多條消息, 或者是別的?途的數(shù)據(jù)那么就需要處理粘包.

?對于處理粘包的問題, 常?的解決?案有:

「多次發(fā)送之前間隔?個等待時間」:只需要等上?段時間再進?下?次 send 就好, 適?于交互頻率特別低的場景. 缺點也很明顯, 對于?較頻繁的場景??傳輸效率實在太低,不過?乎不?做什么處理.

「關(guān)閉 Nagle 算法」:關(guān)閉 Nagle 算法, 在 Node.js 中你可以通過 socket.setNoDelay() ?法來關(guān)閉 Nagle 算法, 讓每?次 send 都不緩沖直接發(fā)送。該?法?較適?于每次發(fā)送的數(shù)據(jù)都?較? (但不是?件那么?), 并且頻率不是特別?的場景。如果是每次發(fā)送的數(shù)據(jù)量?較?, 并且頻率特別?的, 關(guān)閉 Nagle 純屬?廢武功。另外, 該?法不適?于?絡(luò)較差的情況, 因為 Nagle 算法是在服務端進?的包合并情況, 但是如果短時間內(nèi)客戶端的?絡(luò)情況不好, 或者應?層由于某些原因不能及時將 TCP 的數(shù)據(jù) recv, 就會造成多個包在客戶端緩沖從?粘包的情況。(如果是在穩(wěn)定的機房內(nèi)部通信那么這個概率是?較?可以選擇忽略的)

「進?封包/拆包:」 封包/拆包是?前業(yè)內(nèi)常?的解決?案了。即給每個數(shù)據(jù)包在發(fā)送之前, 于其前/后放?些有特征的數(shù)據(jù), 然后收到數(shù)據(jù)的時 候根據(jù)特征數(shù)據(jù)分割出來各個數(shù)據(jù)包。

17. token是什么?
token也可以稱做「令牌」,一般由 uid+time+sign(簽名)+[固定參數(shù)] 組成
uid: 用戶唯一身份標識
time: 當前時間的時間戳
sign: 簽名, 使用 hash/encrypt 壓縮成定長的十六進制字符串,以防止第三方惡意拼接
固定參數(shù)(可選): 將一些常用的固定參數(shù)加入到 token 中是為了避免重復查庫
token在客戶端一般存放于localStorage,cookie,或sessionStorage中。在服務器一般存于數(shù)據(jù)庫中

token 的認證流程

用戶登錄,成功后服務器返回Token給客戶端。
客戶端收到數(shù)據(jù)后保存在客戶端
客戶端再次訪問服務器,將token放入headers中 或者每次的請求 參數(shù)中
服務器端采用filter過濾器校驗。校驗成功則返回請求數(shù)據(jù),校驗失敗則返回錯誤碼
token可以抵抗csrf,cookie+session不行

session時有狀態(tài)的,一般存于服務器內(nèi)存或硬盤中,當服務器采用分布式或集群時,session就會面對負載均衡問題。負載均衡多服務器的情況,不好確認當前用戶是否登錄,因為多服務器不共享session

客戶端登陸傳遞信息給服務端,服務端收到后把用戶信息加密(token)傳給客戶端,客戶端將token存放于localStroage等容器中??蛻舳嗣看卧L問都傳遞token,服務端解密token,就知道這個用戶是誰了。通過cpu加解密,服務端就不需要存儲session占用存儲空間,就很好的解決負載均衡多服務器的問題了。這個方法叫做JWT(Json Web Token)

18. token是怎么加密的
需要一個secret(隨機數(shù))
后端利用secret和加密算法(如:HMAC-SHA256)對payload(如賬號密碼)生成一個字符串(token),返回前端
前端每次request在header中帶上token
后端用同樣的算法解密
19. cookie和token都放在header中,為什么會劫持cookie,不會劫持token
「cookie」: 登陸后后端生成一個sessionid放在cookie中返回給客戶端, 并且服務端一直記錄著這個 sessionid, 客戶端以后每次請求都會帶上這個sessionid, 服務端通過這個sessionid來驗證身份之類的操作。所以別人拿到了cookie就相當于拿到了sessionid ,就可以完全替代你。同時瀏覽器會自動攜帶cookie
token: 同樣是登錄后服務端返回一個token,客戶端保存起來,在以后http請求里手動的加入到請求頭里,服務端根據(jù)token 進行身份的校驗。瀏覽器不會自動攜帶token,所以不會劫持 token。
20. token過期后,頁面如何實現(xiàn)無感刷新?
「什么是無感刷新」

后臺返回的token是有時效性的,時間到了,你在交互后臺的時候,后臺會判斷你的token是否過期(安全需要),如果過期了就會逼迫你重新登陸!

「token無感刷新其本質(zhì)是為了優(yōu)化用戶體驗,當token過期時不需要用戶跳回登錄頁重新登錄,而是當token失效時,進行攔截,發(fā)送刷新token的ajax,獲取最新的token進行覆蓋,讓用戶感受不到token已經(jīng)過期」

「實現(xiàn)無感刷新」

1、后端返回過期時間,前端判斷token過期時間,去調(diào)用刷新token接口。

缺點:需要后端額外提供一個Token過期時間的字段;使用了本地時間判斷,若本地時間篡改,特別是本地時間比服務器時間慢時,攔截會失敗。

2、寫個定時器,定時刷新Token接口。缺點:浪費資源,消耗性能,不建議采用。

3、在響應攔截器中攔截,判斷Token 返回過期后,調(diào)用刷新token接口。

21. 介紹下304過程
a. 瀏覽器請求資源時首先命中資源的Expires 和 Cache-Control,Expires 受限于本地時間,如果修改了本地時間,可能會造成緩存失效,可以通過Cache-control: max-age指定最大生命周期,狀態(tài)仍然返回200,但不會請求數(shù)據(jù),在瀏覽器中能明顯看到from cache字樣。
b. 強緩存失效,進入?yún)f(xié)商緩存階段,首先驗證ETagETag可以保證每一個資源是唯一的,資源變化都會導致ETag變化。服務器根據(jù)客戶端上送的If-None-Match值來判斷是否命中緩存。
c. 協(xié)商緩存Last-Modify/If-Modify-Since階段,客戶端第一次請求資源時,服務服返回的header中會加上Last-Modify,Last-modify是一個時間標識該資源的最后修改時間。再次請求該資源時,request的請求頭中會包含If-Modify-Since,該值為緩存之前返回的Last-Modify。服務器收到If-Modify-Since后,根據(jù)資源的最后修改時間判斷是否命中緩存
三、瀏覽器安全
1. 有哪些可能引起前端安全的問題?
「跨站腳本」 (Cross-Site Scripting, XSS): ?種代碼注??式, 為了與 CSS 區(qū)分所以被稱作 XSS。早期常?于?絡(luò)論壇, 起因是?站沒有對?戶的輸?進?嚴格的限制, 使得攻擊者可以將腳本上傳到帖?讓其他?瀏覽到有惡意腳本的??, 其注??式很簡單包括但不限于 JavaScript / CSS / Flash 等;
「iframe的濫?」: iframe中的內(nèi)容是由第三?來提供的,默認情況下他們不受控制,他們可以在iframe中運?JavaScirpt腳本、Flash插件、彈出對話框等等,這可能會破壞前端?戶體驗;
「跨站點請求偽造」(Cross-Site Request Forgeries,CSRF): 指攻擊者通過設(shè)置好的陷阱,強制對已完成認證的?戶進??預期的個?信息或設(shè)定信息等某些狀態(tài)更新,屬于被動攻擊
「惡意第三?庫」: ?論是后端服務器應?還是前端應?開發(fā),絕?多數(shù)時候都是在借助開發(fā)框架和各種類庫進?快速開發(fā),?旦第三?庫被植?惡意代碼很容易引起安全問題。
2. 網(wǎng)絡(luò)劫持有哪幾種,如何防范?
?絡(luò)劫持分為兩種:

(1)「DNS劫持」: (輸?京東被強制跳轉(zhuǎn)到淘寶這就屬于dns劫持)

DNS強制解析: 通過修改運營商的本地DNS記錄,來引導?戶流量到緩存服務器
302跳轉(zhuǎn)的?式: 通過監(jiān)控?絡(luò)出?的流量,分析判斷哪些內(nèi)容是可以進?劫持處理的,再對劫持的內(nèi)存發(fā)起302跳轉(zhuǎn)的回復,引導?戶獲取內(nèi)容
(2)「HTTP劫持」: (訪問?歌但是?直有貪玩藍?的?告),由于http明?傳輸,運營商會修改你的http響應內(nèi)容(即加?告)

DNS劫持由于涉嫌違法,已經(jīng)被監(jiān)管起來,現(xiàn)在很少會有DNS劫持,?http劫持依然?常盛?,最有效的辦法就是全站HTTPS,將HTTP加密,這使得運營商?法獲取明?,就?法劫持你的響應內(nèi)容。

3. 進程與線程的概念
從本質(zhì)上說,進程和線程都是 CPU 工作時間片的一個描述:

進程描述了 CPU 在運行指令及加載和保存上下文所需的時間,放在應用上來說就代表了一個程序。
線程是進程中的更小單位,描述了執(zhí)行一段指令所需的時間。
「進程是資源分配的最小單位,線程是CPU調(diào)度的最小單位?!?br>
4. 進程和線程的區(qū)別
進程可以看做獨立應用,線程不能
「資源」:進程是cpu資源分配的最小單位(是能擁有資源和獨立運行的最小單位);線程是cpu調(diào)度的最小單位(線程是建立在進程的基礎(chǔ)上的一次程序運行單位,一個進程中可以有多個線程)。
「通信方面」:線程間可以通過直接共享同一進程中的資源,而進程通信需要借助 進程間通信。
「調(diào)度」:進程切換比線程切換的開銷要大。線程是CPU調(diào)度的基本單位,線程的切換不會引起進程切換,但某個進程中的線程切換到另一個進程中的線程時,會引起進程切換。
「系統(tǒng)開銷」:由于創(chuàng)建或撤銷進程時,系統(tǒng)都要為之分配或回收資源,如內(nèi)存、I/O 等,其開銷遠大于創(chuàng)建或撤銷線程時的開銷。同理,在進行進程切換時,涉及當前執(zhí)行進程 CPU 環(huán)境還有各種各樣狀態(tài)的保存及新調(diào)度進程狀態(tài)的設(shè)置,而線程切換時只需保存和設(shè)置少量寄存器內(nèi)容,開銷較小。
5. 如何實現(xiàn)瀏覽器內(nèi)多個標簽頁之間的通信?
實現(xiàn)多個標簽頁之間的通信,本質(zhì)上都是通過中介者模式來實現(xiàn)的。因為標簽頁之間沒有辦法直接通信,因此我們可以找一個中介者,讓標簽頁和中介者進行通信,然后讓這個中介者來進行消息的轉(zhuǎn)發(fā)。通信方法如下:

「使用 websocket 協(xié)議」,因為 websocket 協(xié)議可以實現(xiàn)服務器推送,所以服務器就可以用來當做這個中介者。標簽頁通過向服務器發(fā)送數(shù)據(jù),然后由服務器向其他標簽頁推送轉(zhuǎn)發(fā)。
「使用 ShareWorker 的方式」,shareWorker 會在頁面存在的生命周期內(nèi)創(chuàng)建一個唯一的線程,并且開啟多個頁面也只會使用同一個線程。這個時候共享線程就可以充當中介者的角色。標簽頁間通過共享一個線程,然后通過這個共享的線程來實現(xiàn)數(shù)據(jù)的交換。
「使用 localStorage 的方式」,我們可以在一個標簽頁對 localStorage 的變化事件進行監(jiān)聽,然后當另一個標簽頁修改數(shù)據(jù)的時候,我們就可以通過這個監(jiān)聽事件來獲取到數(shù)據(jù)。這個時候 localStorage 對象就是充當?shù)闹薪檎叩慕巧?br>「使用 postMessage 方法」,如果我們能夠獲得對應標簽頁的引用,就可以使用postMessage 方法,進行通信。






6. 為什么需要瀏覽器緩存?
對于瀏覽器的緩存,主要針對的是前端的靜態(tài)資源,在發(fā)起請求之后,拉取相應的靜態(tài)資源,并保存在本地。如果服務器的靜態(tài)資源沒有更新,那么在下次請求的時候,就直接從本地讀取即可,如果服務器的靜態(tài)資源已經(jīng)更新,那么我們再次請求的時候,就到服務器拉取新的資源,并保存在本地。這樣就大大的減少了請求的次數(shù),提高了網(wǎng)站的性能。這就要用到瀏覽器的緩存策略了。

所謂的「瀏覽器緩存」指的是瀏覽器將用戶請求過的靜態(tài)資源,存儲到電腦本地磁盤中,當瀏覽器再次訪問時,就可以直接從本地加載,不需要再去服務端請求了。

瀏覽器緩存的優(yōu)點
使用瀏覽器緩存,有以下優(yōu)點:

減少了服務器的負擔,提高了網(wǎng)站的性能
加快了客戶端網(wǎng)頁的加載速度
減少了多余網(wǎng)絡(luò)數(shù)據(jù)傳輸
7. 點擊刷新按鈕或者按 F5、按 Ctrl+F5 (強制刷新)、地址欄回車有什么區(qū)別?
「點擊刷新按鈕或者按 F5:」 瀏覽器直接對本地的緩存文件過期,但是會帶上If-Modifed-Since,If-None-Match,這就意味著服務器會對文件檢查新鮮度,返回結(jié)果可能是 304,也有可能是 200。
「用戶按 Ctrl+F5(強制刷新):」 瀏覽器不僅會對本地文件過期,而且不會帶上 If-Modifed-Since,If-None-Match,相當于之前從來沒有請求過,返回結(jié)果是 200。
「地址欄回車」:瀏覽器發(fā)起請求,按照正常流程,本地檢查是否過期,然后服務器檢查新鮮度,最后返回內(nèi)容。
8. 瀏覽器渲染過程中遇到 JS 文件如何處理?
JavaScript 的加載、解析與執(zhí)行會阻塞文檔的解析,也就是說,在構(gòu)建 DOM 時,HTML 解析器若遇到了 JavaScript,那么它會暫停文檔的解析,將控制權(quán)移交給 JavaScript 引擎,等 JavaScript 引擎運行完畢,瀏覽器再從中斷的地方恢復繼續(xù)解析文檔。

也就是說,如果想要首屏渲染的越快,就越不應該在首屏就加載 JS 文件,這也是都建議將 script 標簽放在 body 標簽底部的原因。當然在當下,并不是說 script 標簽必須放在底部,因為你可以給 script 標簽添加 defer 或者 async 屬性。

9. 什么是文檔的預解析?
Webkit 和 Firefox 都做了這個優(yōu)化,當執(zhí)行 JavaScript 腳本時,另一個線程解析剩下的文檔,并加載后面需要通過網(wǎng)絡(luò)加載的資源。這種方式可以使資源并行加載從而使整體速度更快。需要注意的是,預解析并不改變 DOM 樹,它將這個工作留給主解析過程,自己只解析外部資源的引用,比如外部腳本、樣式表及圖片。

10. CSS 如何阻塞文檔解析?
理論上,既然樣式表不改變 DOM 樹,也就沒有必要停下文檔的解析等待它們。然而,存在一個問題,JavaScript 腳本執(zhí)行時可能在文檔的解析過程中請求樣式信息,如果樣式還沒有加載和解析,腳本將得到錯誤的值,顯然這將會導致很多問題。

所以「如果瀏覽器尚未完成 CSSOM 的下載和構(gòu)建,而我們卻想在此時運行腳本,那么瀏覽器將延遲 JavaScript 腳本執(zhí)行和文檔的解析,直至其完成 CSSOM 的下載和構(gòu)建。」 也就是說,在這種情況下,瀏覽器會先下載和構(gòu)建 CSSOM,然后再執(zhí)行 JavaScript,最后再繼續(xù)文檔的解析。

11.瀏覽器本地存儲的方式
Cookie
Cookie是最早被提出來的本地存儲方式,在此之前,服務端是無法判斷網(wǎng)絡(luò)中的兩個請求是否是同一用戶發(fā)起的,為解決這個問題,Cookie就出現(xiàn)了?!窩ookie的大小只有4kb」,它是一種純文本文件,「每次發(fā)起HTTP請求都會攜帶Cookie?!?br>
「Cookie的特性:」

Cookie一旦創(chuàng)建成功,名稱就無法修改
Cookie是無法跨域名的,也就是說a域名和b域名下的cookie是無法共享的,這也是由Cookie的隱私安全性決定的,這樣就能夠阻止非法獲取其他網(wǎng)站的Cookie
每個域名下Cookie的數(shù)量不能超過20個,每個Cookie的大小不能超過4kb
有安全問題,如果Cookie被攔截了,那就可獲得session的所有信息,即使加密也于事無補,無需知道cookie的意義,只要轉(zhuǎn)發(fā)cookie就能達到目的
Cookie在請求一個新的頁面的時候都會被發(fā)送過去
「如果需要域名之間跨域共享Cookie,有兩種方法:」

使用Nginx反向代理
在一個站點登陸之后,往其他網(wǎng)站寫Cookie。服務端的Session存儲到一個節(jié)點,Cookie存儲sessionId
LocalStorage
LocalStorage是HTML5新引入的特性,由于有的時候我們存儲的信息較大,Cookie就不能滿足我們的需求,這時候LocalStorage就派上用場了。

「LocalStorage的優(yōu)點:」

在大小方面,LocalStorage的大小一般為5MB,可以儲存更多的信息
LocalStorage是持久儲存,并不會隨著頁面的關(guān)閉而消失,除非主動清理,不然會永久存在
僅儲存在本地,不像Cookie那樣每次HTTP請求都會被攜帶
「LocalStorage的缺點:」

存在瀏覽器兼容問題,IE8以下版本的瀏覽器不支持
如果瀏覽器設(shè)置為隱私模式,那我們將無法讀取到LocalStorage
LocalStorage受到同源策略的限制,即端口、協(xié)議、主機地址有任何一個不相同,都不會訪問
SessionStorage
SessionStorage和LocalStorage都是在HTML5才提出來的存儲方案,SessionStorage 主要用于臨時保存同一窗口(或標簽頁)的數(shù)據(jù),刷新頁面時不會刪除,關(guān)閉窗口或標簽頁之后將會刪除這些數(shù)據(jù)。

「SessionStorage與LocalStorage對比:」

SessionStorage和LocalStorage都在「本地進行數(shù)據(jù)存儲」;
SessionStorage也有同源策略的限制,但是SessionStorage有一條更加嚴格的限制,SessionStorage「只有在同一瀏覽器的同一窗口下才能夠共享」;
LocalStorage和SessionStorage「都不能被爬蟲爬取」;
12. Cookie、LocalStorage、SessionStorage區(qū)別
「cookie:」 其實最開始是服務器端用于記錄用戶狀態(tài)的一種方式,由服務器設(shè)置,在客戶端存儲,然后每次發(fā)起同源請求時,發(fā)送給服務器端。cookie 最多能存儲 4 k 數(shù)據(jù),它的生存時間由 expires 屬性指定,并且 cookie 只能被同源的頁面訪問共享。

「sessionStorage:」 html5 提供的一種瀏覽器本地存儲的方法,它借鑒了服務器端 session 的概念,代表的是一次會話中所保存的數(shù)據(jù)。它一般能夠存儲 5M 或者更大的數(shù)據(jù),它在當前窗口關(guān)閉后就失效了,并且 sessionStorage 只能被同一個窗口的同源頁面所訪問共享。

「localStorage:」 html5 提供的一種瀏覽器本地存儲的方法,它一般也能夠存儲 5M 或者更大的數(shù)據(jù)。它和 sessionStorage 不同的是,除非手動刪除它,否則它不會失效,并且 localStorage 也只能被同源頁面所訪問共享。

13.什么是同源策略,什么是跨域
「同源策略:protocol(協(xié)議)、domain(域名)、port(端口)三者必須一致?!?br>
「同源政策主要限制了三個方面:」

當前域下的 js 腳本不能夠訪問其他域下的 cookie、localStorage 和 indexDB。
當前域下的 js 腳本不能夠操作訪問操作其他域下的 DOM。
當前域下 ajax 無法發(fā)送跨域請求。
同源政策的目的主要是為了保證用戶的信息安全,它只是對 js 腳本的一種限制,并不是對瀏覽器的限制,對于一般的 img、或者script 腳本請求都不會有跨域的限制,這是因為這些操作都不會通過響應結(jié)果來進行可能出現(xiàn)安全問題的操作。

「什么是跨域」

指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本,它是由瀏覽器的同源策略造成的,是瀏覽器對 javascript 施加的安全限制,防止他人惡意攻擊網(wǎng)站

「跨域問題其實就是瀏覽器的同源策略造成的?!?br>
14. 如何解決跨越問題
「CORS」
CORS需要瀏覽器和服務器同時支持,整個CORS過程都是瀏覽器完成的,無需用戶參與。因此實現(xiàn)「CORS的關(guān)鍵就是服務器,只要服務器實現(xiàn)了CORS請求」,就可以跨源通信了。

「JSONP」
「jsonp」的原理就是利用<script>標簽沒有跨域限制,通過<script>標簽src屬性,發(fā)送帶有callback參數(shù)的GET請求,服務端將接口返回數(shù)據(jù)拼湊到callback函數(shù)中,返回給瀏覽器,瀏覽器解析執(zhí)行,從而前端拿到callback函數(shù)返回的數(shù)據(jù)

「優(yōu)點」

實現(xiàn)簡單
兼容性好, 可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。
「缺點」

只支持 GET 請求 ( 因為
存在被 XSS 攻擊的可能, 缺乏安全性保證
需要服務端配合改造
「postMessage」
postMessage是HTML5 XMLHttpRequest Level 2中的API,且是為數(shù)不多可以跨域操作的window屬性之一,它可用于解決以下方面的問題:

頁面和其打開的新窗口的數(shù)據(jù)傳遞
多窗口之間消息傳遞
頁面與嵌套的iframe消息傳遞
上面三個場景的跨域數(shù)據(jù)傳遞
用法:postMessage(data,origin)方法接受兩個參數(shù):

「data」:html5規(guī)范支持任意基本類型或可復制的對象,但部分瀏覽器只支持字符串,所以傳參時最好用JSON.stringify()序列化。
「origin」:協(xié)議+主機+端口號,也可以設(shè)置為"*",表示可以傳遞給任意窗口,如果要指定和當前窗口同源的話設(shè)置為"/"。
「Node中間件代理(proxy正向代理)(兩次跨域)」
實現(xiàn)原理:「同源策略是瀏覽器需要遵循的標準,而如果是服務器向服務器請求就無需遵循同源策略。」 代理服務器,需要做以下幾個步驟:

接受客戶端請求 。
將請求 轉(zhuǎn)發(fā)給服務器。
拿到服務器 響應 數(shù)據(jù)。
「nginx反向代理」
實現(xiàn)原理類似于Node中間件代理,需要你搭建一個中轉(zhuǎn)nginx服務器,用于轉(zhuǎn)發(fā)請求。

使用nginx反向代理實現(xiàn)跨域,是最簡單的跨域方式。只需要修改nginx的配置即可解決跨域問題,支持所有瀏覽器,支持session,不需要修改任何代碼,并且不會影響服務器性能。

實現(xiàn)思路:通過nginx配置一個代理服務器(域名與domain1相同,端口不同)做跳板機,反向代理訪問domain2接口,并且可以順便修改cookie中domain信息,方便當前域cookie寫入,實現(xiàn)跨域登錄。

15. 正向代理和反向代理的區(qū)別
「正向代理:」
客戶端想獲得一個服務器的數(shù)據(jù),但是因為種種原因無法直接獲取。于是客戶端設(shè)置了一個代理服務器,并且指定目標服務器,之后代理服務器向目標服務器轉(zhuǎn)交請求并將獲得的內(nèi)容發(fā)送給客戶端。這樣本質(zhì)上起到了對真實服務器隱藏真實客戶端的目的。實現(xiàn)正向代理需要修改客戶端,比如修改瀏覽器配置。

「反向代理:」
服務器為了能夠?qū)⒐ぷ髫撦d分不到多個服務器來提高網(wǎng)站性能 (負載均衡)等目的,當其受到請求后,會首先根據(jù)轉(zhuǎn)發(fā)規(guī)則來確定請求應該被轉(zhuǎn)發(fā)到哪個服務器上,然后將請求轉(zhuǎn)發(fā)到對應的真實服務器上。這樣本質(zhì)上起到了對客戶端隱藏真實服務器的作用。一般使用反向代理后,需要通過修改 DNS 讓域名解析到代理服務器 IP,這時瀏覽器無法察覺到真正服務器的存在,當然也就不需要修改配置了。



16. 前端安全了解嗎,說一下 XSS 和 CSRF,以及怎么規(guī)避
「XSS」:跨域腳本攻擊

XSS 攻擊指的是跨站腳本攻擊,是一種代碼注入攻擊。攻擊者通過在網(wǎng)站注入惡意腳本,使之在用戶的瀏覽器上運行,從而盜取用戶的信息如 cookie 等。

XSS 的本質(zhì)是因為網(wǎng)站沒有對惡意代碼進行過濾,與正常的代碼混合在一起了,瀏覽器沒有辦法分辨哪些腳本是可信的,從而導致了惡意代碼的執(zhí)行。

攻擊者可以通過這種攻擊方式可以進行以下操作:

獲取頁面的數(shù)據(jù),如DOM、cookie、localStorage;
DOS攻擊,發(fā)送合理請求,占用服務器資源,從而使用戶無法訪問服務器;
破壞頁面結(jié)構(gòu);
流量劫持(將鏈接指向某網(wǎng)站);
「防御方法」

可以從瀏覽器的執(zhí)行來進行預防,一種是使用純前端的方式,不用服務器端拼接后返回(不使用服務端渲染)。另一種是對需要插入到 HTML 中的代碼做好充分的轉(zhuǎn)義。對于 DOM 型的攻擊,主要是前端腳本的不可靠而造成的,對于數(shù)據(jù)獲取渲染和字符串拼接的時候應該對可能出現(xiàn)的惡意代碼情況進行判斷。

「CSRF」:跨站請求偽造

CSRF 攻擊指的是「跨站請求偽造攻擊」,攻擊者誘導用戶進入一個第三方網(wǎng)站,然后該網(wǎng)站向被攻擊網(wǎng)站發(fā)送跨站請求。如果用戶在被攻擊網(wǎng)站中保存了登錄狀態(tài),那么攻擊者就可以利用這個登錄狀態(tài),繞過后臺的用戶驗證,冒充用戶向服務器執(zhí)行一些操作。

CSRF 攻擊的「本質(zhì)是利用 cookie 會在同源請求中攜帶發(fā)送給服務器的特點,以此來實現(xiàn)用戶的冒充?!?br>
「CSRF 攻擊可以使用以下方法來防護:」

「進行同源檢測」,服務器根據(jù) http 請求頭中 origin 或者 referer 信息來判斷請求是否為允許訪問的站點,從而對請求進行過濾。
「使用 CSRF Token 進行驗證」,服務器向用戶返回一個隨機數(shù) Token ,當網(wǎng)站再次發(fā)起請求時,在請求參數(shù)中加入服務器端返回的 token ,然后服務器對這個 token 進行驗證。
「對 Cookie 進行雙重驗證」,服務器在用戶訪問網(wǎng)站頁面時,向請求域名注入一個Cookie,內(nèi)容為隨機字符串,然后當用戶再次向服務器發(fā)送請求的時候,從 cookie 中取出這個字符串,添加到 URL 參數(shù)中,然后服務器通過對 cookie 中的數(shù)據(jù)和參數(shù)中的數(shù)據(jù)進行比較,來進行驗證。
「在設(shè)置 cookie 屬性的時候設(shè)置 Samesite ,限制 cookie 不能作為被第三方使用」,從而可以避免被攻擊者利用。Samesite 一共有兩種模式,一種是嚴格模式,在嚴格模式下 cookie 在任何情況下都不可能作為第三方 Cookie 使用,在寬松模式下,cookie 可以被請求是 GET 請求,且會發(fā)生頁面跳轉(zhuǎn)的請求所使用。
什么是中間人攻擊?
中間? (Man-in-the-middle attack, MITM) 是指攻擊者與通訊的兩端分別創(chuàng)建獨?的聯(lián)系, 并交換其所收到的數(shù)據(jù), 使通訊的兩端認為他們正在通過?個私密的連接與對?直接對話, 但事實上整個會話都被攻擊者完全控制。在中間?攻擊中,攻擊者可以攔截通訊雙?的通話并插?新的內(nèi)容。

攻擊過程如下:

客戶端發(fā)送請求到服務端,請求被中間?截獲
服務器向客戶端發(fā)送公鑰
中間?截獲公鑰,保留在???上。然后???成?個「偽造的」公鑰,發(fā)給客戶端
客戶端收到偽造的公鑰后,?成加密hash值發(fā)給服務器
中間?獲得加密hash值,???的私鑰解密獲得真秘鑰,同時?成假的加密hash值,發(fā)給服務器
服務器?私鑰解密獲得假密鑰,然后加密數(shù)據(jù)傳輸給客戶端
17. 瀏覽器是如何進行界面渲染的?
不同的渲染引擎的具體做法稍有差異,但是大體流程都是差不多的,下面以 chrome渲染引擎 的 渲染流程來說明:

獲取 HTML ?件并進?解析,生成一棵 DOM 樹(DOM Tree)
解析 HTML 的同時也會解析 CSS,?成樣式規(guī)則(Style Rules)
根據(jù) DOM 樹和樣式規(guī)則,生成一棵渲染樹(Render Tree)
進行布局(Layout)(重排),即為每個節(jié)點分配?個在屏幕上應顯示的確切坐標位置
進?繪制(Paint)(重繪),遍歷渲染樹節(jié)點,調(diào)? GPU(圖形處理器) 將元素呈現(xiàn)出來
18. 前端如何實現(xiàn)即時通訊?websocket
嚴格意義上: HTTP協(xié)議只能做到客戶端請求服務器, 服務器做出響應, 做不到讓服務器主動給客戶端推送消息!

「那么如果服務器數(shù)據(jù)更新了, 想要即時通知到客戶端怎么辦呢 ? (即時通信需求)」

即時通信需求: 服務器數(shù)據(jù)一有更新, 希望推送給到瀏覽器

提問的回答重心:

即時通信有哪些方案?
為什么使用了其中某一個方案! websocket
基于Web的前端,存在以下幾種可實現(xiàn)即時通訊的方式:

短輪詢 (歷史方案)

開個定時器, 每隔一段時間發(fā)請求 (實時性不強,影響性能)

Comet - ajax長輪詢(歷史方案)

發(fā)送一個請求, 服務器只要數(shù)據(jù)不更新, 就一直阻塞 (服務器壓力過大)

SSE

(利用了http協(xié)議, 流數(shù)據(jù)的傳輸, 并不是嚴格意義的雙向通信, 無法復用連接)

WebSocket (主流)

性能和效率都高!

19. 說一下websocket
「websocket是一種網(wǎng)絡(luò)通信協(xié)議」,是HTML5開始提供的一種在單個TCP連接上進行全雙工通信的協(xié)議,這個對比著HTTP協(xié)議來說,HTTP協(xié)議是一種無狀態(tài)的、無連接的、單向的應用層協(xié)議,通信請求只能由客戶端發(fā)起,服務端對請求做出應答處理。

「HTTP協(xié)議無法實現(xiàn)服務器主動向客戶端發(fā)起消息」,websocket連接允許客戶端和服務器之間進行全雙工通信,以便任一方都可以通過建立的連接將數(shù)據(jù)推送到另一端。websocket只需要建立一次連接,就可以一直保持連接狀態(tài)

19.2 什么是輪詢
「輪詢:隔一段時間進行一次查詢或者詢問」

輪詢分為長輪詢和短輪詢,長輪詢是基于短輪詢的一個優(yōu)化結(jié)果。

「短輪詢:」

通過客戶端定期輪詢來詢問服務端是否有新的信息產(chǎn)生,如果有則返回,沒有就不響應, 缺點:也是顯而易見,輪詢間隔大了則信息不夠?qū)崟r,輪詢間隔過小又會消耗過多的流量,增加服務器的負擔。

「長輪詢:」

是需要服務端進行更改來進行支持,客戶端向服務端發(fā)送請求時,如果此時服務端沒有新的信息產(chǎn)生,并不立刻返回,而是Hold住一段時間等有新的信息或者超時再返回,客戶端收到服務器的應答后繼續(xù)輪詢??梢钥吹介L輪詢比短輪詢可以減少大量無用的請求,并且客戶端接收取新消息也會實時不少。減少http請求對性能的優(yōu)化是很有利的,所以他是短輪詢上的一個優(yōu)化 缺點:終歸來講還是一個http請求,只是進行了變化而已,而且如果客戶端不請求,服務端有數(shù)據(jù)的話,也會一直累積在那,不能實現(xiàn)實時的雙向通信

此時的webSocket也就「應需而生」了

20. 前端怎么做SEO優(yōu)化
「什么是SEO」

SEO(Search Engine Optimization),即搜索引擎優(yōu)化。SEO是隨著搜索引擎的出現(xiàn)而來的,兩者是相互促進,互利共生的關(guān)系。SEO的存在就是為了提升網(wǎng)頁在搜索引擎自然搜索結(jié)果中的收錄數(shù)量以及排序位置而做的優(yōu)化行為。而優(yōu)化的目的就是為了提升網(wǎng)站在搜索引擎中的權(quán)重,增加對搜索引擎的友好度,使得用戶在訪問網(wǎng)站時能排在前面。

「為什么要做SEO」

提高網(wǎng)站的權(quán)重,增強搜索引擎友好度,以達到提高排名,增加流量,改善(潛在)用戶體驗,促進銷售的作用。

「前端怎么做SEO優(yōu)化」

網(wǎng)站結(jié)構(gòu)布局優(yōu)化: 盡量簡單

控制首頁鏈接數(shù)量
網(wǎng)頁層級不要太深
控制頁面大小, 減少HTTP請求, 提高網(wǎng)站的加載速度
盡量使用語義化標簽
利用瀏覽器緩存

本文轉(zhuǎn)載自:https://juejin.cn/post/7149438206419664927

作者:逍丶




作者:逍丶


歡迎關(guān)注微信公眾號 :前端Q