前端知識(shí)匯總(網(wǎng)絡(luò)篇)

  1. https 4次握手
  • c端請(qǐng)求,s端響應(yīng)并提供證書(包括公鑰、證書信息、頒發(fā)機(jī)構(gòu)、過(guò)期時(shí)間等,s端私鑰加密生成);
  • c端校驗(yàn)接收數(shù)據(jù)(主要是校驗(yàn)公鑰確實(shí)是s端發(fā)的,見(jiàn)數(shù)字證書部分)后,生成pre-master-secret并使用s端發(fā)過(guò)來(lái)的公鑰加密;
  • s端接收到后使用私鑰解密,并最終通過(guò)某種算法生成master-secret;
  • 后續(xù)的通信中s和c端均使用這個(gè)master-secret生成的密鑰。
    (其中兩個(gè)secret是為了提高隨機(jī)性,減少隨機(jī)數(shù)被猜出的風(fēng)險(xiǎn))
  1. 數(shù)字證書發(fā)布過(guò)程
  • 服務(wù)器生成一對(duì)密鑰,私鑰自己留著,公鑰交給數(shù)字證書認(rèn)證機(jī)構(gòu)(CA) 。
  • CA進(jìn)行審核,并用自己的私鑰對(duì)服務(wù)器的公鑰進(jìn)行簽名。
  • 客戶端訪問(wèn)服務(wù)器時(shí),從CA獲取證書(包括服務(wù)器端公鑰),用CA的公鑰對(duì)簽名的證書進(jìn)行驗(yàn)證,一致則說(shuō)明該服務(wù)器公鑰確實(shí)是CA頒發(fā)的。
  1. https涉及的加密算法
  • 非對(duì)稱加密(非對(duì)稱加密算法用于握手過(guò)程中的加密生成的密碼)
    RSA,DSA/DSS
  • 對(duì)稱加密(對(duì)真正傳輸?shù)臄?shù)據(jù)進(jìn)行加密):AES,RC4,3DES
  • HASH(用于驗(yàn)證數(shù)據(jù)的完整性,是否被篡改等):MD5,SHA1,SHA256
    非對(duì)稱加密生成密碼是整個(gè)加密過(guò)程的關(guān)鍵,非對(duì)稱加密會(huì)生成公鑰和私鑰,公鑰負(fù)責(zé)數(shù)據(jù)加密,可以隨意傳輸。私鑰負(fù)責(zé)解密。
  1. https如何優(yōu)化
  • http使用TCP 三次握手建立連接,客戶端和服務(wù)器需要交換3個(gè)包,https除了 TCP 的三個(gè)包,還要加上 SSL握手需要的9個(gè)包,所以一共是12個(gè)包。
  • https的開(kāi)銷主要是SSL部分(尤其是session建立階段)。主要是網(wǎng)絡(luò)延時(shí)和SSL本身加解密的開(kāi)銷(服務(wù)器根據(jù)客戶端的信息確定是否需要生成新的主密鑰;服務(wù)器回復(fù)該主密鑰,并返回給客戶端一個(gè)用主密鑰認(rèn)證的信息;服務(wù)器向客戶端請(qǐng)求數(shù)字簽名和公開(kāi)密鑰)。
  • 可以通過(guò)負(fù)載均衡的SSL termination proxy來(lái)優(yōu)化,Web 服務(wù)放在SSL termination proxy之后。SSL termination proxy可以是基于硬件的,譬如F5;也可以軟件的,如Nginx(維基百科用的)。
  • 另外也可以通過(guò)SSL session或SSL ticket復(fù)用來(lái)優(yōu)化。session ID就是每一次對(duì)話都有一個(gè)編號(hào)(session ID)。只要客戶端給出這個(gè)編號(hào),且服務(wù)器有這個(gè)編號(hào)的記錄,雙方就可以重新使用已有的"對(duì)話密鑰",但session ID 往往只保留在一臺(tái)服務(wù)器上;而session ticket類似,但是加密的,只有服務(wù)器才能解密,其中包括本次對(duì)話的主要信息,比如對(duì)話密鑰和加密方法。當(dāng)服務(wù)器收到 session ticket 以后,解密后就不必重新生成對(duì)話密鑰了,支持負(fù)載均衡。
  • (Heartbleed就是RFC 在2012年提出了 RFC6520 TLS 的心跳擴(kuò)展用于優(yōu)化SSL所引起的漏洞。原本希望通過(guò)在客戶端和服務(wù)器之間來(lái)回發(fā)送心跳的請(qǐng)求和應(yīng)答,保活 TLS session,減少重建 TLS的session的性能開(kāi)銷,但未對(duì)心跳請(qǐng)求進(jìn)行長(zhǎng)度檢查,導(dǎo)致客戶端可以讀服務(wù)器內(nèi)存的數(shù)據(jù)。)
  1. http2特性
  • http的語(yǔ)義、頭部、狀態(tài)碼、方法等不受影響
  • 服務(wù)器端推送消息
  • 傳輸二進(jìn)制幀而非文本(亂序發(fā)幀并收到后重組)
  • 僅在一個(gè)TCP連接中并行處理(通過(guò)請(qǐng)求優(yōu)先級(jí)控制)
  • 壓縮頭部信息減小開(kāi)銷
  • 在客戶端和服務(wù)器端使用“首部表”來(lái)跟蹤和存儲(chǔ)之前發(fā)送的鍵-值對(duì),對(duì)于相同的數(shù)據(jù),不再通過(guò)每次請(qǐng)求和響應(yīng)發(fā)送
  1. 從輸入url到渲染的整個(gè)過(guò)程
  • 客戶端DNS尋址(瀏覽器DNS緩存、操作系統(tǒng)DNS緩存、本地域名服務(wù)器、向根域名服務(wù)器發(fā)送迭代請(qǐng)求)獲得目標(biāo)IP(有可能是CDN的IP)。
  • TCP或UDP連接建立。
  • 數(shù)據(jù)經(jīng)過(guò)路由器到運(yùn)營(yíng)商網(wǎng)絡(luò),經(jīng)過(guò)層層轉(zhuǎn)發(fā)到達(dá)服務(wù)器。
  • 數(shù)據(jù)經(jīng)過(guò)負(fù)載均衡(F5,LVS,反向代理)
  • 數(shù)據(jù)到達(dá)web server,經(jīng)過(guò)后端業(yè)務(wù)邏輯
  • 如果采用SSR(服務(wù)器端渲染),則后端調(diào)用數(shù)據(jù)(數(shù)據(jù)庫(kù)等)生成應(yīng)用代碼,如果是前后端分離架構(gòu),則數(shù)據(jù)和網(wǎng)頁(yè)文件分別返回。
  • 數(shù)據(jù)通過(guò)網(wǎng)絡(luò)回到客戶端(內(nèi)網(wǎng)NAT穿透)
  • 數(shù)據(jù)到達(dá)瀏覽器,如有g(shù)zip壓縮先解壓,開(kāi)始編碼(這里要注意是utf-8還是gbk)
  • html被解析(DOM樹(shù)、CSSDOM樹(shù)、呈現(xiàn)樹(shù)等,見(jiàn)上面問(wèn)題),加載外部資源,文字、圖片渲染至屏幕。
  1. TCP三次握手,四次揮手過(guò)程
  • 三次握手


    三次握手
  • 四次揮手


    四次揮手
  1. CDN加速原理
  • 用戶向?yàn)g覽器輸入www.web.com這個(gè)域名,瀏覽器第一次發(fā)現(xiàn)本地沒(méi)有DNS緩存,則向根域名服務(wù)器發(fā)起請(qǐng)求。
  • 根域名服務(wù)器設(shè)置了CNAME,指向了www.cdn.com,即CDN網(wǎng)絡(luò)中的智能DNS負(fù)載均衡系統(tǒng)。
  • 智能DNS負(fù)載均衡系統(tǒng)解析域名,把對(duì)用戶響應(yīng)速度最快的IP節(jié)點(diǎn)返回給用戶。
  • 用戶向該IP節(jié)點(diǎn)(CDN服務(wù)器)發(fā)出請(qǐng)求。
  • 由于是第一次訪問(wèn),CDN服務(wù)器會(huì)向原web站點(diǎn)請(qǐng)求,并緩存內(nèi)容。
  • 請(qǐng)求結(jié)果發(fā)給用戶。
  1. 靜態(tài)資源優(yōu)化
  • 配置超長(zhǎng)時(shí)間的本地緩存(cache-control/expires) —— 節(jié)省帶寬,提高性能
  • 采用hash值作為緩存更新依據(jù) —— 精確的緩存控制
  • 靜態(tài)資源CDN部署 —— 優(yōu)化網(wǎng)絡(luò)請(qǐng)求
  • 更新資源發(fā)布路徑實(shí)現(xiàn)非覆蓋式發(fā)布 —— 平滑升級(jí)
  1. 為何很多網(wǎng)站靜態(tài)資源會(huì)使用獨(dú)立的域名
  • 靜態(tài)資源的http請(qǐng)求中不會(huì)攜帶無(wú)用的cookie。
  • 動(dòng)靜分離更有利于CDN。
  • http對(duì)同一個(gè)域名的同時(shí)下載線程數(shù)是有限制的,只要是為了優(yōu)化下載速度,防止一個(gè)域名下太多下載線程,每個(gè)瀏覽器的限制不同。
  • 方便復(fù)用,放在另一個(gè)服務(wù)器上,可以方便全局內(nèi)其他產(chǎn)品的使用,比如說(shuō)taobao.com的js tmall也可以用,且客戶端可緩存。
  1. 跨域解決
  • JSONP:僅支持get方法。原理是通過(guò)標(biāo)簽的src屬性引用的文件可以跨域,那么傳回一個(gè)腳本,將數(shù)據(jù)包在腳本中回調(diào)函數(shù)里并動(dòng)態(tài)執(zhí)行就可以拿到函數(shù)中的數(shù)據(jù)。
  • CORS:后端配置Access-Control-Allow-Origin(IE10+)。注意包括簡(jiǎn)單請(qǐng)求和復(fù)雜請(qǐng)求。
  • 代理:正向反向都可(nginx)
  1. CORS的簡(jiǎn)單請(qǐng)求和復(fù)雜請(qǐng)求
    方法為HEAD,GET,POST之一,且headers只包括Accept, Accept-Language, Content-Language, Last-Event-ID, Content-Type(值為application/x-www-form-urlencoded, multipart/form-data, text/plain之一)的請(qǐng)求為簡(jiǎn)單請(qǐng)求。
  • 簡(jiǎn)單請(qǐng)求瀏覽器直接發(fā)出,只添加一個(gè)origin頭,服務(wù)器若允許該origin,則在響應(yīng)頭加上Access-Control-Allow-Origin: origin的值表示允許跨域。
    Access-Control-Allow-Credentials控制服務(wù)器是否接受Cookies,如果不為true但是傳了Cookies,則前端會(huì)報(bào)異常(注意,如果接受Cookies則origin的值不能為星號(hào))。
    Access-Control-Expose-Headers用來(lái)控制前端可以拿哪些響應(yīng)頭的header。
  • 復(fù)雜請(qǐng)求瀏覽器會(huì)先發(fā)一個(gè)OPTION方法的preflight請(qǐng)求。預(yù)檢請(qǐng)求中Access-Control-Request-Method用來(lái)標(biāo)志此次復(fù)雜請(qǐng)求的方法,Access-Control-Request-Headers表明復(fù)雜請(qǐng)求額外發(fā)送的header字段。服務(wù)器檢查origin及method、header后,如果接受則類似簡(jiǎn)單請(qǐng)求發(fā)送響應(yīng),僅多一個(gè)Access-Control-Max-Age來(lái)標(biāo)志預(yù)檢的有效期。
  1. 自己寫一個(gè)jsonp的實(shí)現(xiàn)
var JSONP = {
    now: function() { // 獲取當(dāng)前時(shí)間戳
        return (new Date()).getTime();
    },
    rand: function() { // 獲取隨機(jī)數(shù)
        return Math.random().toString().substr(2);
    },
    removeElem: function(elem) {
        var parent = elem.parentNode;
        if(parent && parent.nodeType !== 11) {
            parent.removeChild(elem);
        }
    },
    parseData: function(data) {  // url組裝
        var ret = "";
        if(typeof data === "string") {
            ret = data;
        }else if(typeof data === "object") {
            for(var key in data) {
                ret += "&" + key + "=" + encodeURIComponent(data[key]);
            }
        }
        ret += "&_time=" + this.now();// 加個(gè)時(shí)間戳,防止緩存
        ret = ret.substr(1);
        return ret;
    },
    getJSON: function(url, data, func) {  // 函數(shù)名稱
        var name;
        url = url + (url.indexOf("?") === -1 ? "?" : "&") + this.parseData(data); // 拼裝url
        var match = /callback=(\w+)/.exec(url); // 檢測(cè)callback的函數(shù)名是否已經(jīng)定義
        if(match && match[1]) {
            name = match[1];
        } else {
            // 如果未定義函數(shù)名的話隨機(jī)成一個(gè)函數(shù)名
            // 隨機(jī)生成的函數(shù)名通過(guò)時(shí)間戳拼16位隨機(jī)數(shù)的方式,重名的概率基本為0
            // 如:jsonp_1355750852040_8260732076596469
            name = "jsonp_" + this.now() + '_' + this.rand();
            url = url.replace("callback=?", "callback="+name);// 把callback中的?替換成函數(shù)名
            url = url.replace("callback=%3F", "callback="+name);// 處理?被encode的情況
        }  
        var script = document.createElement("script"); // 創(chuàng)建一個(gè)script元素
        script.type = "text/javascript";
        script.src = url; // 設(shè)置要遠(yuǎn)程的url
        script.id = "id_" + name;   // 設(shè)置id,為了后面可以刪除這個(gè)元素

        // 把傳進(jìn)來(lái)的函數(shù)重新組裝,并把它設(shè)置為全局函數(shù),遠(yuǎn)程就是調(diào)用這個(gè)函數(shù)
        window[name] = function(json) {
            window[name] = undefined; // 執(zhí)行這個(gè)函數(shù)后,要銷毀這個(gè)函數(shù)
            var elem = document.getElementById("id_" + name); // 獲取這個(gè)script的元素
            JSONP.removeElem(elem);  // 刪除head里面插入的script,這三步都是為了不影響污染整個(gè)DOM啊
            func(json);  // 執(zhí)行傳入的的函數(shù)
        };  
        var head = document.getElementsByTagName("head");  // 在head里面插入script元素
        if(head && head[0]) {
            head[0].appendChild(script);
        }
    }
};
//調(diào)用的方法跟jQuery基本一樣。如:
var data = {
            from: "北京",
            count: 27,
            output: "json",
            callback: "?"
        }
JSONP.getJSON("http://api.qunar.com/cdnWebservices.jcp", data, function(json) {console.log(json)});
  1. 原生ajax
<script>
 // 1.獲得ajax
 if (window.XMLHttpRequest) { //查看當(dāng)前瀏覽器XMLHttpRequest是否是全局變量
     var oAjax = new XMLHttpResquest();
 } else {
     var oAjax = new ActiveXObject('Microsoft.XMLHTTP'); //IE6,傳入微軟參數(shù)
 }

 // 2.打開(kāi)地址
 switch (json.type.toLowerCase()) {
     case 'get':
         oAjax.open('GET', json.url + '?' + jsonToURL(json.data), true); // 提交方式(大寫),url,是否異步
// 3.發(fā)送GET數(shù)據(jù)
         oAjax.send();
         break;
     case 'post':
         oAjax.open('POST', json.url, true);
         oAjax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
         oAjax.send(jsonToURL(json.data)); 
// 3.發(fā)送POST數(shù)據(jù)
        break;
 }

 // 4.接收數(shù)據(jù)
 oAjax.onreadystatechange = function() { //監(jiān)控狀態(tài)
     if (oAjax.readyState == 4) {
         json.complete && json.complete();
         if (oAjax.status >= 200 && oAjax.status < 300 ||
             oAjax.status == 304) {
             json.success && json.success(oAjax.responseText); //執(zhí)行成功的回調(diào)函數(shù), responseText為響應(yīng)內(nèi)容
         } else {
             json.error && json.error(oAjax.status); //執(zhí)行失敗的回調(diào)函數(shù)
         }
     }
 };
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,715評(píng)論 19 139
  • <a name='html'>HTML</a> Doctype作用?標(biāo)準(zhǔn)模式與兼容模式各有什么區(qū)別? (1)、<...
    clark124閱讀 3,861評(píng)論 1 19
  • 本文轉(zhuǎn)發(fā)自github, 原文地址 <a name='js'>JavaScript</a> 介紹js的基本數(shù)據(jù)類型...
    XDUZ閱讀 1,171評(píng)論 1 11
  • 二點(diǎn)十分去連云港的火車,睡到了兩點(diǎn)半才醒,去改簽了。
    M2112閱讀 199評(píng)論 0 0
  • 我家大姑娘八歲了,二年級(jí)剛結(jié)束。昨天晚飯后,跟我說(shuō)悄悄話:媽媽我告訴你一個(gè)秘密,我們班上有兩對(duì)情侶! 我?guī)е眯Φ?..
    海藍(lán)26閱讀 545評(píng)論 0 0

友情鏈接更多精彩內(nèi)容