<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前端基礎(chǔ)知識(shí)整理匯總(上)

          共 15112字,需瀏覽 31分鐘

           ·

          2021-02-25 21:27



          又是一年跳槽季,最近聽(tīng)到最多的消息就是,我們公司又有同事離職了,所以,如果你想在職場(chǎng)上掌握主動(dòng)權(quán),你就需要比別人更加努力,更加夯實(shí)的技能基礎(chǔ),不然你拿什么去跟別人拼?所以,今天我們跟大家分享一些前端基礎(chǔ)知識(shí),希望對(duì)你有所幫助。
          HTML頁(yè)面的生命周期

          HTML頁(yè)面的生命周期有以下三個(gè)重要事件:

          • DOMContentLoaded —— 瀏覽器已經(jīng)完全加載了 HTML,DOM 樹(shù)已經(jīng)構(gòu)建完畢,但是像是?// 帶有src屬性的元素不應(yīng)該在標(biāo)簽之間包含額外的js代碼,即使包含,只會(huì)下載并執(zhí)行外部文件,內(nèi)部代碼也會(huì)被忽略。

            與嵌入式j(luò)s代碼一樣, 在解析外部js文件時(shí),頁(yè)面的處理會(huì)暫時(shí)停止。

            改變腳本行為的方法

            1. defer: 立即下載,延遲執(zhí)行

            加載和渲染后續(xù)文檔元素的過(guò)程將和腳本的加載并行進(jìn)行(異步),但是腳本的執(zhí)行會(huì)在所有元素解析完成之后。腳本總會(huì)按照聲明順序執(zhí)行。
            在DOMContentLoaded事件之前執(zhí)行。

            2. async: 異步腳本

            加載和渲染后續(xù)文檔元素的過(guò)程將和腳本的加載與執(zhí)行并行進(jìn)行(異步)。但是async?在下載完畢后的執(zhí)行會(huì)阻塞HTML的解析。腳本加載后馬上執(zhí)行,不能保證異步腳本按照他們?cè)陧?yè)面中出現(xiàn)的順序執(zhí)行。
            一定會(huì)在load事件之前執(zhí)行,可能會(huì)在DOMContentLoaded事件之前或之后執(zhí)行。

            區(qū)別:

            meta

            META標(biāo)簽是HTML標(biāo)記HEAD區(qū)的一個(gè)關(guān)鍵標(biāo)簽,它提供的信息雖然用戶不可見(jiàn),但卻是文檔的最基本的元信息。除了提供文檔字符集、使用語(yǔ)言、作者等網(wǎng)頁(yè)相關(guān)信息外,還可以設(shè)置信息給搜索引擎,目的是為了SEO(搜索引擎優(yōu)化)。

            HTML 元素表示那些不能由其它 HTML 元相關(guān)(meta-related)元素((,

            后臺(tái)代碼:

              $callback = $_GET['callback'];//得到回調(diào)函數(shù)名  $data = array('a','b','c');//要返回的數(shù)據(jù)  echo $callback.'('.json_encode($data).')';//輸出?>

            CORS - 跨域資源共享

            CORS是一個(gè)W3C標(biāo)準(zhǔn),全稱是"跨域資源共享"(Cross-origin resource sharing)。

            CORS有兩種請(qǐng)求,簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求。只要同時(shí)滿足以下兩大條件,就屬于簡(jiǎn)單請(qǐng)求。

            1. 請(qǐng)求方法是以下三種方法之一:HEAD,GET,POST

            2. HTTP的頭信息不超出以下幾種字段:Accept,Accept-Language,Content-Language,Last-Event-ID,Content-Type【只限于三個(gè)值application/x-www-form-urlencoded、multipart/form-data、text/plain】,沒(méi)有自定義的HTTP頭部。

            簡(jiǎn)單請(qǐng)求

            1. 瀏覽器:把客戶端腳本所在的域填充到Origin header里,向其他域的服務(wù)器請(qǐng)求資源。

            2. 服務(wù)器:根據(jù)資源權(quán)限配置,在響應(yīng)頭中添加Access-Control-Allow-Origin Header,返回結(jié)果。

            3. 瀏覽器:比較服務(wù)器返回的Access-Control-Allow-Origin Header和請(qǐng)求域的Origin。如果當(dāng)前域已經(jīng)得到授權(quán),則將結(jié)果返回給頁(yè)面。否則瀏覽器忽略此次響應(yīng)。

            4. 網(wǎng)頁(yè):收到返回結(jié)果或者瀏覽器的錯(cuò)誤提示。

            對(duì)于簡(jiǎn)單的跨域請(qǐng)求,只要服務(wù)器設(shè)置的Access-Control-Allow-Origin?Header和請(qǐng)求來(lái)源匹配,瀏覽器就允許跨域服務(wù)器端設(shè)置的`Access-Control-Allow-MethodsAccess-Control-Allow-Headers對(duì)簡(jiǎn)單跨域沒(méi)有作用。

            非簡(jiǎn)單請(qǐng)求

            1. 瀏覽器:先向服務(wù)器發(fā)送一個(gè)OPTIONS預(yù)檢請(qǐng)求,檢測(cè)服務(wù)器端是否支持真實(shí)請(qǐng)求進(jìn)行跨域資源訪問(wèn),瀏覽器會(huì)在發(fā)送OPTIONS請(qǐng)求時(shí)會(huì)自動(dòng)添加Origin Header 、Access-Control-Request-Method Header和Access-Control-Request-Headers Header。

            2. 服務(wù)器:響應(yīng)OPTIONS請(qǐng)求,會(huì)在responseHead里添加Access-Control-Allow-Methods?head。這其中的method的值是服務(wù)器給的默認(rèn)值,可能不同的服務(wù)器添加的值不一樣。服務(wù)器還會(huì)添加Access-Control-Allow-Origin?Header和Access-Control-Allow-Headers?Header。這些取決于服務(wù)器對(duì)OPTIONS請(qǐng)求具體如何做出響應(yīng)。如果服務(wù)器對(duì)OPTIONS響應(yīng)不合你的要求,你可以手動(dòng)在服務(wù)器配置OPTIONS響應(yīng),以應(yīng)對(duì)帶預(yù)檢的跨域請(qǐng)求。在配置服務(wù)器OPTIONS的響應(yīng)時(shí),可以添加Access-Control-Max-Age head告訴瀏覽器在一定時(shí)間內(nèi)無(wú)需再次發(fā)送預(yù)檢請(qǐng)求,但是如果瀏覽器禁用緩存則無(wú)效。

            3. 瀏覽器:接到OPTIONS的響應(yīng),比較真實(shí)請(qǐng)求的method是否屬于返回的Access-Control-Allow-Methods?head的值之一,還有origin, head也會(huì)進(jìn)行比較是否匹配。如果通過(guò),瀏覽器就繼續(xù)向服務(wù)器發(fā)送真實(shí)請(qǐng)求, 否則就會(huì)報(bào)預(yù)檢錯(cuò)誤:請(qǐng)求來(lái)源不被options響應(yīng)允許,請(qǐng)求方法不被options響應(yīng)允許或請(qǐng)求中有自定義header不被options響應(yīng)允許。

            4. 服務(wù)器:響應(yīng)真實(shí)請(qǐng)求,在響應(yīng)頭中放入Access-Control-Allow-Origin?Header、Access-Control-Allow-MethodsAccess-Control-Allow-Headers?Header,分別表示允許跨域資源請(qǐng)求的域、請(qǐng)求方法和請(qǐng)求頭,并返回?cái)?shù)據(jù)。

            5. 瀏覽器:接受服務(wù)器對(duì)真實(shí)請(qǐng)求的返回結(jié)果,返回給網(wǎng)頁(yè)

            6. 網(wǎng)頁(yè):收到返回結(jié)果或者瀏覽器的錯(cuò)誤提示。

            Access-Control-Allow-Origin在響應(yīng)options請(qǐng)求和響應(yīng)真實(shí)請(qǐng)求時(shí)都是有作用的,兩者必須同時(shí)包含要跨域的源。?Access-Control-Allow-MethodsAccess-Control-Allow-Headers只在響應(yīng)options請(qǐng)求時(shí)有作用。

            攜帶cookie

            在 CORS 跨域中,瀏覽器并不會(huì)自動(dòng)發(fā)送 Cookie。對(duì)于普通跨域請(qǐng)求只需服務(wù)端設(shè)置,而帶cookie跨域請(qǐng)求前后端都需要設(shè)置。

            瀏覽器,對(duì)于跨域請(qǐng)求,需要設(shè)置withCredentials?屬性為 true。服務(wù)端的響應(yīng)中必須攜帶?Access-Control-Allow-Credentials: true?。

            除了Access-Control-Allow-Credentials之外,跨域發(fā)送 Cookie 還要求?Access-Control-Allow-Origin不允許使用通配符。否則瀏覽器將會(huì)拋出The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*'?錯(cuò)誤。事實(shí)上不僅不允許通配符,而且只能指定單一域名。

            計(jì)算 Access-Control-Allow-Origin

            既然Access-Control-Allow-Origin只允許單一域名, 服務(wù)器可能需要維護(hù)一個(gè)接受 Cookie 的 Origin 列表, 驗(yàn)證?Origin?請(qǐng)求頭字段后直接將其設(shè)置為Access-Control-Allow-Origin的值。在 CORS 請(qǐng)求被重定向后?Origin?頭字段會(huì)被置為?null, 此時(shí)可以選擇從Referer頭字段計(jì)算得到Origin

            具體實(shí)現(xiàn)

            服務(wù)器端的響應(yīng)頭配置
            Access-Control-Allow-Origin 可以設(shè)置為*?,表示可以與任意域進(jìn)行數(shù)據(jù)共享。
            // 設(shè)置服務(wù)器接受跨域的域名"Access-Control-Allow-Origin": "http://127.0.0.1:8080",// 設(shè)置服務(wù)器接受跨域的請(qǐng)求方法'Access-Control-Allow-Methods': 'OPTIONS,HEAD,DELETE,GET,PUT,POST',// 設(shè)置服務(wù)器接受跨域的headers'Access-Control-Allow-Headers': 'x-requested-with, accept, origin, content-type',// 設(shè)置服務(wù)器不用再次預(yù)檢請(qǐng)求時(shí)間'Access-Control-Max-Age': 10000,// 設(shè)置服務(wù)器接受跨域發(fā)送Cookie'Access-Control-Allow-Credentials': true

            document.domain

            此方案僅限主域相同,子域不同的跨域應(yīng)用場(chǎng)景。

            實(shí)現(xiàn)原理:兩個(gè)頁(yè)面都通過(guò)js強(qiáng)制設(shè)置document.domain為基礎(chǔ)主域,就實(shí)現(xiàn)了同域。

            栗子:

            在父頁(yè)面?http://xxx.com/a.html?中設(shè)置document.domain

            在子頁(yè)面http://xxx.com/b.html?中設(shè)置document.domain

            window.postMessage

            window.postMessage是html5的功能,是客戶端和客戶端直接的數(shù)據(jù)傳遞,既可以跨域傳遞,也可以同域傳遞。

            postMessage(data, origin)方法接受兩個(gè)參數(shù):

            • data:html5規(guī)范支持任意基本類型或可復(fù)制的對(duì)象,但部分瀏覽器只支持字符串,所以傳參時(shí)最好用JSON.stringify()序列化。

            • origin:協(xié)議+主機(jī)+端口號(hào),也可以設(shè)置為"*",表示可以傳遞給任意窗口,如果要指定和當(dāng)前窗口同源的話設(shè)置為"/"。

            栗子:
            假如有一個(gè)頁(yè)面,頁(yè)面中拿到部分用戶信息,點(diǎn)擊進(jìn)入另外一個(gè)頁(yè)面,另外的頁(yè)面默認(rèn)是取不到用戶信息的,你可以通過(guò)window.postMessage把部分用戶信息傳到這個(gè)頁(yè)面中。(需要考慮安全性等方面。)

            發(fā)送消息:

            // 彈出一個(gè)新窗口var domain = 'http://haorooms.com';var myPopup = window.open(`${domain}/windowPostMessageListener.html`,'myWindow');
            // 發(fā)送消息setTimeout(function(){ var message = {name:"站點(diǎn)",sex:"男"}; console.log('傳遞的數(shù)據(jù)是 ' + message); myPopup.postMessage(message, domain);}, 1000);

            接收消息:

            // 監(jiān)聽(tīng)消息反饋window.addEventListener('message', function(event) {  // 判斷域名是否正確  if (event.origin !== 'http://haorooms.com') return;  console.log('received response: ', event.data);}, false);

            如下圖,接受頁(yè)面得到數(shù)據(jù)

            如果是使用iframe,代碼應(yīng)該這樣寫(xiě):

            // 捕獲iframevar domain = 'http://haorooms.com';var iframe = document.getElementById('myIFrame').contentWindow;
            // 發(fā)送消息setTimeout(function(){ var message = {name:"站點(diǎn)",sex:"男"}; console.log('傳遞的數(shù)據(jù)是: ' + message); iframe.postMessage(message, domain); },1000);

            接收數(shù)據(jù)并反饋信息:

            // 響應(yīng)事件window.addEventListener('message',function(event) {    if(event.origin !== 'http://haorooms.com') return;    console.log('message received:  ' + event.data, event);    event.source.postMessage(event.origin);}, false);

            幾個(gè)比較重要的事件屬性:
            source – 消息源,消息的發(fā)送窗口/iframe。
            origin – 消息源的URI(可能包含協(xié)議、域名和端口),用來(lái)驗(yàn)證數(shù)據(jù)源。
            data – 發(fā)送方發(fā)送給接收方的數(shù)據(jù)。

            window.name

            原理:
            window對(duì)象有個(gè)name屬性,該屬性有個(gè)特征:即在一個(gè)窗口(window)的生命周期內(nèi),窗口載入的所有的頁(yè)面都是共享一個(gè)window.name,每個(gè)頁(yè)面對(duì)window.name都有讀寫(xiě)的權(quán)限,window.name是持久存在一個(gè)窗口載入過(guò)的所有頁(yè)面中的。

            栗子:
            在子頁(yè)面(b.com/data.html) 設(shè)置window.name:

            /* b.com/data.html */

            在父頁(yè)面(a.com/app.html)中創(chuàng)建一個(gè)iframe,把其src指向子頁(yè)面。在父頁(yè)面監(jiān)聽(tīng)iframe的onload事件,獲取子頁(yè)面數(shù)據(jù):

            /* a.com/app.html */

            http-proxy-middleware

            http-proxy-middleware用于把請(qǐng)求代理轉(zhuǎn)發(fā)到其他服務(wù)器的中間件。
            安裝:
            npm install http-proxy-middleware --save-dev
            配置如下:

            module.exports = {  devServer: {    contentBase: path.resolve(__dirname, 'dev'),    publicPath: '/',    historyApiFallback: true,    proxy: {      // 請(qǐng)求到 '/device' 下的請(qǐng)求都會(huì)被代理到target:http://target.com中      '/device/*': {        target: 'http://target.com',        secure: false, // 接受運(yùn)行在https上的服務(wù)        changeOrigin: true      }    }  }}

            使用如下:

            fetch('/device/space').then(res => {  // 被代理到 http://target.com/device/space  return res.json();});
            // 使用的url 必須以/開(kāi)始 否則不會(huì)代理到指定地址fetch('device/space').then(res => { // http://localhost:8080/device/space 訪問(wèn)本地服務(wù) return res.json();});

            nginx反向代理

            反向代理(Reverse Proxy)方式是指以代理服務(wù)器來(lái)接受客戶端的連接請(qǐng)求,然后將請(qǐng)求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器;并將從服務(wù)器上得到的結(jié)果返回給客戶端,此時(shí)代理服務(wù)器對(duì)外就表現(xiàn)為一個(gè)服務(wù)器。

            反向代理服務(wù)器對(duì)于客戶端而言它就像是原始服務(wù)器,并且客戶端不需要進(jìn)行任何特別的設(shè)置。客戶端向反向代理 的命名空間(name-space)中的內(nèi)容發(fā)送普通請(qǐng)求,接著反向代理將判斷向何處(原始服務(wù)器)轉(zhuǎn)交請(qǐng)求,并將獲得的內(nèi)容返回給客戶端,就像這些內(nèi)容 原本就是它自己的一樣。

            模塊化

            AMD/CMD/CommonJs都是JS模塊化開(kāi)發(fā)的標(biāo)準(zhǔn),目前對(duì)應(yīng)的實(shí)現(xiàn)是RequireJS,SeaJs, nodeJs;

            CommonJS:服務(wù)端js

            CommonJS 是以在瀏覽器環(huán)境之外構(gòu)建 javaScript 生態(tài)系統(tǒng)為目標(biāo)而產(chǎn)生的寫(xiě)一套規(guī)范,主要是為了解決 javaScript 的作用域問(wèn)題而定義的模塊形式,可以使每個(gè)模塊它自身的命名空間中執(zhí)行。

            實(shí)現(xiàn)方法:模塊必須通過(guò) module.exports 導(dǎo)出對(duì)外的變量或者接口,通過(guò) require() 來(lái)導(dǎo)入其他模塊的輸出到當(dāng)前模塊的作用域中;

            主要針對(duì)服務(wù)端(同步加載文件)和桌面環(huán)境中,node.js 遵循的是 CommonJS 的規(guī)范;CommonJS 加載模塊是同步的,所以只有加載完成才能執(zhí)行后面的操作。

            • require()用來(lái)引入外部模塊;

            • exports對(duì)象用于導(dǎo)出當(dāng)前模塊的方法或變量,唯一的導(dǎo)出口;

            • module對(duì)象就代表模塊本身。

            // 定義一個(gè)module.js文件var A = () => console.log('我是定義的模塊');
            // 1.第一種返回方式module.exports = A; // 2.第二種返回方式 module.exports.test = A// 3.第三種返回方式 exports.test = A;
            // 定義一個(gè)test.js文件【這兩個(gè)文件在同一個(gè)目錄下】var module = require("./module");
            //調(diào)用這個(gè)模塊,不同的返回方式用不同的方式調(diào)用// 1.第一種調(diào)用方式module();// 2.第二種調(diào)用方式 module.test();// 3.第三種調(diào)用方式 module.test();
            // 執(zhí)行文件node test.js

            AMD:異步模塊定義【瀏覽器端js】

            AMD 是 Asynchronous Module Definition 的縮寫(xiě),意思是異步模塊定義;采用的是異步的方式進(jìn)行模塊的加載,在加載模塊的時(shí)候不影響后邊語(yǔ)句的運(yùn)行。主要是為前端 js 的表現(xiàn)指定的一套規(guī)范。

            實(shí)現(xiàn)方法:通過(guò)define方法去定義模塊,通過(guò)require方法去加載模塊。
            define(id?,dependencies?,factory): 它要在聲明模塊的時(shí)候制定所有的依賴(dep),并且還要當(dāng)做形參傳到factory中。沒(méi)什么依賴,就定義簡(jiǎn)單的模塊(或者叫獨(dú)立的模塊)
            require([modules], callback): 第一個(gè)參數(shù)[modules],是需加載的模塊名數(shù)組;第二個(gè)參數(shù)callback,是模塊加載成功之后的回調(diào)函數(shù)

            主要針對(duì)瀏覽器js,requireJs遵循的是 AMD 的規(guī)范;

            // module1.js文件, 定義獨(dú)立的模塊define({    methodA: () => console.log('我是module1的methodA');    methodB: () => console.log('我是module1的methodB');});
            // module2.js文件, 另一種定義獨(dú)立模塊的方式define(() => { return { methodA: () => console.log('我是module2的methodA'); methodB: () => console.log('我是module2的methodB'); };});
            // module3.js文件, 定義非獨(dú)立的模塊(這個(gè)模塊依賴其他模塊)define(['module1', 'module2'], (m1, m2) => { return { methodC: () => { m1.methodA(); m2.methodB(); } };});

            //定義一個(gè)main.js,去加載這些個(gè)模塊require(['module3'], (m3) => { m3.methodC();});

            // 為避免造成網(wǎng)頁(yè)失去響應(yīng),解決辦法有兩個(gè),一個(gè)是把它放在網(wǎng)頁(yè)底部加載,另一個(gè)是寫(xiě)成下面這樣:// async屬性表明這個(gè)文件需要異步加載,避免網(wǎng)頁(yè)失去響應(yīng)。// IE不支持這個(gè)屬性,只支持defer,所以把defer也寫(xiě)上。
            // data-main屬性: 指定網(wǎng)頁(yè)程序的主模塊
            // 控制臺(tái)輸出結(jié)果我是module1的methodA我是module2的methodB

            CMD:通用模塊定義【瀏覽器端js】

            CMD 是 Common Module Definition 的縮寫(xiě),通過(guò)異步的方式進(jìn)行模塊的加載的,在加載的時(shí)候會(huì)把模塊變?yōu)樽址馕鲆槐椴胖酪蕾嚵四膫€(gè)模塊;

            主要針對(duì)瀏覽器端(異步加載文件),按需加載文件。對(duì)應(yīng)的實(shí)現(xiàn)是seajs

            AMD和CMD的區(qū)別

            1. 對(duì)于依賴的模塊,AMD 是提前執(zhí)行,CMD 是延遲執(zhí)行。不過(guò) RequireJS 從 2.0 開(kāi)始,也改成可以延遲執(zhí)行(根據(jù)寫(xiě)法不同,處理方式不同)。CMD 推崇 as lazy as possible(盡可能的懶加載,也稱為延遲加載,即在需要的時(shí)候才加載)。

            2. CMD 推崇依賴就近,AMD 推崇依賴前置。

            // CMDdefine(function(require, exports, module) {    var a = require('./a');    a.doSomething();    // ...    var b = require('./b');   // 依賴可以就近書(shū)寫(xiě)    b.doSomething();    // ... })
            // AMDdefine(['./a', './b'], function(a, b) { // 依賴必須一開(kāi)始就寫(xiě)好 a.doSomething(); // ... b.doSomething(); //...})

            import和require區(qū)別

            import和require都是被模塊化使用。

            • require是CommonJs的語(yǔ)法(AMD規(guī)范引入方式),CommonJs的模塊是對(duì)象。import是es6的一個(gè)語(yǔ)法標(biāo)準(zhǔn)(瀏覽器不支持,本質(zhì)是使用node中的babel將es6轉(zhuǎn)碼為es5再執(zhí)行,import會(huì)被轉(zhuǎn)碼為require),es6模塊不是對(duì)象。

            • require是運(yùn)行時(shí)加載整個(gè)模塊(即模塊中所有方法),生成一個(gè)對(duì)象,再?gòu)膶?duì)象上讀取它的方法(只有運(yùn)行時(shí)才能得到這個(gè)對(duì)象,不能在編譯時(shí)做到靜態(tài)化),理論上可以用在代碼的任何地方。import是編譯時(shí)調(diào)用,確定模塊的依賴關(guān)系,輸入變量(es6模塊不是對(duì)象,而是通過(guò)export命令指定輸出代碼,再通過(guò)import輸入,只加載import中導(dǎo)的方法,其他方法不加載),import具有提升效果,會(huì)提升到模塊的頭部(編譯時(shí)執(zhí)行)

            export和import可以位于模塊中的任何位置,但是必須是在模塊頂層,如果在其他作用域內(nèi),會(huì)報(bào)錯(cuò)(es6這樣的設(shè)計(jì)可以提高編譯器效率,但沒(méi)法實(shí)現(xiàn)運(yùn)行時(shí)加載)。

            • require是賦值過(guò)程,把require的結(jié)果(對(duì)象,數(shù)字,函數(shù)等),默認(rèn)是export的一個(gè)對(duì)象,賦給某個(gè)變量(復(fù)制或淺拷貝)。import是解構(gòu)過(guò)程(需要誰(shuí),加載誰(shuí))。

            require/exports:

            // require: 真正被require出來(lái)的是來(lái)自module.exports指向的內(nèi)存塊內(nèi)容const a = require('a') //
            // exports: 只是 module.exports的引用,輔助module.exports操作內(nèi)存中的數(shù)據(jù)exports.a = a module.exports = a

            import/export:

            // importimport a from 'a';import { default as a  } from 'a';import  *  as a  from 'a';import { fun1,fun2 } from 'a';// exportexport default a;export const a = 1;export functon a { ... };export { fun1, fun2 };
            http和https

            Http:超文本傳輸協(xié)議(Http,HyperText Transfer Protocol)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議。設(shè)計(jì)Http最初的目的是為了提供一種發(fā)布和接收HTML頁(yè)面的方法。它可以使瀏覽器更加高效。

            Http協(xié)議是以明文方式發(fā)送信息的,如果黑客截取了Web瀏覽器和服務(wù)器之間的傳輸報(bào)文,就可以直接獲得其中的信息。

            Https:是以安全為目標(biāo)的Http通道,是Http的安全版。Https的安全基礎(chǔ)是SSL。SSL協(xié)議位于TCP/IP協(xié)議與各種應(yīng)用層協(xié)議之間,為數(shù)據(jù)通訊提供安全支持。SSL協(xié)議可分為兩層:SSL記錄協(xié)議(SSL Record Protocol),它建立在可靠的傳輸協(xié)議(如TCP)之上,為高層協(xié)議提供數(shù)據(jù)封裝、壓縮、加密等基本功能的支持。

            SSL握手協(xié)議(SSL Handshake Protocol),它建立在SSL記錄協(xié)議之上,用于在實(shí)際的數(shù)據(jù)傳輸開(kāi)始前,通訊雙方進(jìn)行身份認(rèn)證、協(xié)商加密算法、交換加密密鑰等。

            HTTP與HTTPS的區(qū)別

            1、HTTP是超文本傳輸協(xié)議,信息是明文傳輸,HTTPS是具有安全性的SSL加密傳輸協(xié)議。
            2、HTTPS協(xié)議需要ca申請(qǐng)證書(shū),一般免費(fèi)證書(shū)少,因而需要一定費(fèi)用。
            3、HTTP和HTTPS使用的是完全不同的連接方式,用的端口也不一樣。前者是80,后者是443。
            4、HTTP連接是無(wú)狀態(tài)的,HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,安全性高于HTTP協(xié)議。

            https的優(yōu)點(diǎn)

            盡管HTTPS并非絕對(duì)安全,掌握根證書(shū)的機(jī)構(gòu)、掌握加密算法的組織同樣可以進(jìn)行中間人形式的攻擊,但HTTPS仍是現(xiàn)行架構(gòu)下最安全的解決方案,主要有以下幾個(gè)好處:

            1)使用HTTPS協(xié)議可認(rèn)證用戶和服務(wù)器,確保數(shù)據(jù)發(fā)送到正確的客戶機(jī)和服務(wù)器;
            2)HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,要比http協(xié)議安全,可防止數(shù)據(jù)在傳輸過(guò)程中不被竊取、改變,確保數(shù)據(jù)的完整性。
            3)HTTPS是現(xiàn)行架構(gòu)下最安全的解決方案,雖然不是絕對(duì)安全,但它大幅增加了中間人攻擊的成本。
            4)谷歌曾在2014年8月份調(diào)整搜索引擎算法,并稱“比起同等HTTP網(wǎng)站,采用HTTPS加密的網(wǎng)站在搜索結(jié)果中的排名將會(huì)更高”。

            Https的缺點(diǎn)

            1)Https協(xié)議握手階段比較費(fèi)時(shí),會(huì)使頁(yè)面的加載時(shí)間延長(zhǎng)近。
            2)Https連接緩存不如Http高效,會(huì)增加數(shù)據(jù)開(kāi)銷,甚至已有的安全措施也會(huì)因此而受到影響;
            3)SSL證書(shū)通常需要綁定IP,不能在同一IP上綁定多個(gè)域名,IPv4資源不可能支撐這個(gè)消耗。
            4)Https協(xié)議的加密范圍也比較有限。最關(guān)鍵的,SSL證書(shū)的信用鏈體系并不安全,特別是在某些國(guó)家可以控制CA根證書(shū)的情況下,中間人攻擊一樣可行。

            遍歷方法

            for

            在for循環(huán)中,循環(huán)取得數(shù)組或是數(shù)組類似對(duì)象的值,譬如arguments和HTMLCollection對(duì)象。

            不足:

            • 在于每次循環(huán)的時(shí)候數(shù)組的長(zhǎng)度都要去獲取;

            • 終止條件要明確;

            foreach(),map()

            兩個(gè)方法都可以遍歷到數(shù)組的每個(gè)元素,而且參數(shù)一致;
            forEach(): 對(duì)數(shù)組的每個(gè)元素執(zhí)行一次提供的函數(shù), 總是返回undefined;
            map(): 創(chuàng)建一個(gè)新數(shù)組,其結(jié)果是該數(shù)組中的每個(gè)元素都調(diào)用一個(gè)提供的函數(shù)后返回的結(jié)果。返回值是一個(gè)新的數(shù)組;

            var array1 = [1,2,3,4,5];
            var x = array1.forEach((value,index) => { console.log(value); return value + 10;});console.log(x); // undefined
            var y = array1.map((value,index) => { console.log(value); return value + 10;});console.log(y); // [11, 12, 13, 14, 15]

            for in

            經(jīng)常用來(lái)迭代對(duì)象的屬性或數(shù)組的每個(gè)元素,它包含當(dāng)前屬性的名稱或當(dāng)前數(shù)組元素的索引。
            當(dāng)遍歷一個(gè)對(duì)象的時(shí)候,變量 i 是循環(huán)計(jì)數(shù)器 為 對(duì)象的屬性名, 以任意順序遍歷一個(gè)對(duì)象的可枚舉屬性。對(duì)于每個(gè)不同的屬性,語(yǔ)句都會(huì)被執(zhí)行。
            當(dāng)遍歷一個(gè)數(shù)組的時(shí)候,變量 i 是循環(huán)計(jì)數(shù)器 為 當(dāng)前數(shù)組元素的索引

            不足:

            for..in循環(huán)會(huì)把某個(gè)類型的原型(prototype)中方法與屬性給遍歷出來(lái).

            const array = ["admin","manager","db"]; array.color = 'red';array.prototype.name= "zhangshan"; for(var i in array){    if(array.hasOwnProperty(i)){         console.log(array[i]);  // admin,manager,db,color    }}// hasOwnProperty(): 對(duì)象的屬性或方法是非繼承的,返回true

            for … of

            迭代循環(huán)可迭代對(duì)象(包括Array,Map,Set,String,TypedArray,arguments 對(duì)象)等等。不能遍歷對(duì)象。只循環(huán)集合本身的元素

            var a = ['A', 'B', 'C'];var s = new Set(['A', 'B', 'C']);var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);a.name = 'array';for (var x of a) { console.log(x); //'A', 'B', 'C'}for (var x of s) { console.log(x);//'A', 'B', 'C'}for (var x of m) { console.log(x[0] + '=' + x[1]);//1='x',2='y',3='z'}
            繼承

            // 定義一個(gè)動(dòng)物類function Animal(name) {  // 屬性  this.name = name || 'Animal';  // 實(shí)例方法  this.sleep = function(){    console.log(this.name + '正在睡覺(jué)!');  }}// 原型方法Animal.prototype.eat = function(food) {  console.log(this.name + '正在吃:' + food);};

            原型鏈繼承

            核心:?將父類的實(shí)例作為子類的原型。

            function Dog(age) {  this.age = age;}Dog.protoType = New Animal();Dog.prototype.name = 'dog';
            const dog = new Dog(12);console.log(dog.name);console.log(dog.eat('age'));console.log(dog instanceof Animal); //true console.log(dog instanceof Dog); //true

            new 創(chuàng)建新實(shí)例對(duì)象經(jīng)過(guò)了以下幾步:

            1.創(chuàng)建一個(gè)新對(duì)象
            2.將新對(duì)象的_proto_指向構(gòu)造函數(shù)的prototype對(duì)象
            3.將構(gòu)造函數(shù)的作用域賦值給新對(duì)象 (也就是this指向新對(duì)象)
            4.執(zhí)行構(gòu)造函數(shù)中的代碼(為這個(gè)新對(duì)象添加屬性)
            5.返回新的對(duì)象

            // 1. 創(chuàng)建一個(gè)新對(duì)象var Obj = {};// 2. 將新對(duì)象的_proto_指向構(gòu)造函數(shù)的prototype對(duì)象Obj._proto_ =  Animal.prototype();// 3. 執(zhí)行構(gòu)造函數(shù)中的代碼(為這個(gè)新對(duì)象添加屬性) Animal.call(Obj);// 4. 返回新的對(duì)象return Obj;

            特點(diǎn):
            1.實(shí)例可繼承的屬性有:實(shí)例的構(gòu)造函數(shù)的屬性,父類構(gòu)造函數(shù)屬性,父類原型的屬性
            2.非常純粹的繼承關(guān)系,實(shí)例是子類的實(shí)例,也是父類的實(shí)例
            3.父類新增原型方法/原型屬性,子類都能訪問(wèn)到

            缺點(diǎn):
            1.新實(shí)例無(wú)法向父類構(gòu)造函數(shù)傳參。
            2.繼承單一。
            3.所有新實(shí)例都會(huì)共享父類實(shí)例的屬性。(原型上的屬性是共享的,一個(gè)實(shí)例修改了原型屬性,另一個(gè)實(shí)例的原型屬性也會(huì)被修改!)
            4.要想為子類新增原型上的屬性和方法,必須要在new Animal()這樣的語(yǔ)句之后執(zhí)行,不能放到構(gòu)造器中

            構(gòu)造函數(shù)繼承

            核心:使用父類的構(gòu)造函數(shù)來(lái)增強(qiáng)子類實(shí)例,等于是復(fù)制父類的實(shí)例屬性給子類(沒(méi)用到原型)

            function Dog(name) {  Animal.apply(this, 'dog');  this.name = name;}
            const dog = new Dog();console.log(dog.name);console.log(dog.eat('age'));console.log(dog instanceof Animal); //false console.log(dog instanceof Dog); //true

            重點(diǎn):用.call()和.apply()將父類構(gòu)造函數(shù)引入子類函數(shù)(在子類函數(shù)中做了父類函數(shù)的自執(zhí)行(復(fù)制))

            特點(diǎn):
            1.只繼承了父類構(gòu)造函數(shù)的屬性,沒(méi)有繼承父類原型的屬性。
            2.解決了原型鏈繼承缺點(diǎn)1、2、3。
            3.可以實(shí)現(xiàn)多繼承,繼承多個(gè)構(gòu)造函數(shù)屬性(call多個(gè))。
            4.在子實(shí)例中可向父實(shí)例傳參。

            缺點(diǎn):
            1.能繼承父類構(gòu)造函數(shù)的屬性。
            2.無(wú)法實(shí)現(xiàn)構(gòu)造函數(shù)的復(fù)用。(每次用每次都要重新調(diào)用)
            3.每個(gè)新實(shí)例都有父類構(gòu)造函數(shù)的副本,臃腫。
            4.實(shí)例并不是父類的實(shí)例,只是子類的實(shí)例

            組合繼承(原型鏈繼承和構(gòu)造函數(shù)繼承)(常用)

            核心:通過(guò)調(diào)用父類構(gòu)造,繼承父類的屬性并保留傳參的優(yōu)點(diǎn),然后通過(guò)將父類實(shí)例作為子類原型,實(shí)現(xiàn)函數(shù)復(fù)用

            function Cat(name){  Animal.call(this, name);  this.name = name;}Cat.prototype = new Animal();Cat.prototype.constructor = Cat;
            var cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // true

            重點(diǎn):結(jié)合了兩種模式的優(yōu)點(diǎn),傳參和復(fù)用

            特點(diǎn):
            1.可以繼承父類原型上的屬性,可以傳參,可復(fù)用。
            2.每個(gè)新實(shí)例引入的構(gòu)造函數(shù)屬性是私有的。
            3.既是子類的實(shí)例,也是父類的實(shí)例

            缺點(diǎn):
            調(diào)用了兩次父類構(gòu)造函數(shù)(耗內(nèi)存),子類的構(gòu)造函數(shù)會(huì)代替原型上的那個(gè)父類構(gòu)造函數(shù)。

            原型式繼承

                

            重點(diǎn):用一個(gè)函數(shù)包裝一個(gè)對(duì)象,然后返回這個(gè)函數(shù)的調(diào)用,這個(gè)函數(shù)就變成了個(gè)可以隨意增添屬性的實(shí)例或?qū)ο蟆bject.create()就是這個(gè)原理。

            特點(diǎn):
            類似于復(fù)制一個(gè)對(duì)象,用函數(shù)來(lái)包裝。

            缺點(diǎn):
            1.所有實(shí)例都會(huì)繼承原型上的屬性。
            2.無(wú)法實(shí)現(xiàn)復(fù)用。(新實(shí)例屬性都是后面添加的)

            寄生式繼承

              
              
            重點(diǎn):就是給原型式繼承外面套了個(gè)殼子。
            優(yōu)點(diǎn):沒(méi)有創(chuàng)建自定義類型,因?yàn)橹皇翘琢藗€(gè)殼子返回對(duì)象(這個(gè)),這個(gè)函數(shù)順理成章就成了創(chuàng)建的新對(duì)象。
            缺點(diǎn):沒(méi)用到原型,無(wú)法復(fù)用。

            寄生組合式繼承(常用)

            寄生:在函數(shù)內(nèi)返回對(duì)象然后調(diào)用
            組合:
            1、函數(shù)的原型等于另一個(gè)實(shí)例。
            2、在函數(shù)中用apply或者call引入另一個(gè)構(gòu)造函數(shù),可傳參。

            function Cat(name){  Animal.call(this);  this.name = name || 'Tom';}(function(){  // 創(chuàng)建一個(gè)沒(méi)有實(shí)例方法的類  var Super = function(){};  Super.prototype = Animal.prototype;  //將實(shí)例作為子類的原型  Cat.prototype = new Super();})();
            var cat = new Cat();Cat.prototype.constructor = Cat; // 需要修復(fù)下構(gòu)造函數(shù)console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); //true

            重點(diǎn):修復(fù)了組合繼承的問(wèn)題。

            本文完?

          瀏覽 67
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  丰满大爆乳波霸奶一区 | 超碰人人澡人人看 | 高清无码成人在线观看 | 久久成人三级片影院 | 99久草视频网 |