秋招后的一些記錄,看了很多東西想寫下來,希望自己可以隨時的查看,也希望有錯誤的地方大神可以指正,
1、瀏覽器的主要組成部分
用戶界面、瀏覽器引擎、呈現引擎、網路、用戶界面后端、JavaScript解釋器、資料存盤,
2、本地存盤
1、cookie簡單介紹
cookie一般被問簡單的介紹,然后cookie的設定、讀取以及是否自動攜帶的問題,通常在多頁面中會被詢問怎么進行資料分享,cookie的降域是一種,接下來詳細介紹這些相關的東西,
簡單介紹
開始設計是為了解決HTTP在狀態管理上的不足(HTTP協議是無狀態的協議),
內部以鍵值對的方式存盤,
向同一個域名下發送請求,都會攜帶相同的Cookie,
服務器拿到Cookie進行決議,便拿到了客戶端的狀態,
作用
可以用來做狀態存盤
缺點
1、容量缺陷:4KB,
2、性能缺陷:Cookie緊跟域名,不管域名下某個地址需不需要Cookie,請求都會攜帶上完整的Cookie,
3、安全缺陷:由于Cookie以純文本的形式在瀏覽器和服務器中傳遞,很容易被非法用戶截取,然后進行篡改,另外,在HTTPOnly為false的情況下,Cookie資訊只能通過JS腳本來讀取,
2、cookie屬性
name屬性簡單介紹
一個域名下系結的cookie,name不能相同,相同的name的值會被覆寫掉,
value屬性簡單介紹
cookie的Name屬性和Value屬性都不允許有逗號,分號,空格的存在,因此如果有著三種形式的符號存在的話,需要將其進行編碼,
domain屬性簡單介紹(降域)
這個是指的域名,這個代表的是,cookie系結的域名,
如果沒有設定,就會自動系結到執行陳述句的當前域,還有值得注意的點,統一個域名下的二級域名也是不可以交換使用cookie的,
例如:你設定www.baidu.com和image.baidu.com,依舊是不能公用的
A網頁是http://w1.example.com/a.html,B網頁是http://w2.example.com/b.html,那么只要設定相同的document.domain,兩個網頁就可以共享Cookie,
降域操作:
document.domain = 'example.com';
多頁面共享資料的時候可以考慮降域的操作進行共享資料,
path屬性
path這個屬性默認是’/’,這個值匹配的是web的路由,
3、cookie的有效期
介紹
如果你想要cookie存在一段時間,那么你可以通過設定Expires屬性為未來的一個時間節點(Expires/Cache-control),
1、Max-Age為正數時,cookie會在Max-Age秒之后,被洗掉,
2、當Max-Age為負數時,表示的是臨時儲存,不會生出cookie檔案,只會存在瀏覽器記憶體中,且只會在打開的瀏覽器視窗或者子視窗有效,一旦瀏覽器關閉,cookie就會消失(為負數時,瀏覽器關閉就失效),
3、當Max-Age為0時,又會發生什么呢,洗掉cookie,因為cookie機制本身沒有設定洗掉cookie,失效的cookie會被瀏覽器自動從記憶體中洗掉,所以,它實作的就是讓cookie失效(為0時,實作了讓cookie失效),
設定
1、 使用Cookie的: Expires 屬性. 它可以設定cookie的過期時間.,
2、使用Cookie的: Max-Age 屬性. 它可以指定從現在開始Cookie存在的秒數. 秒數過完則cookie過期,
Set-Cookie: id=xxxxxx; Max-Age=86400
注意:
1、Expires設定的過期時間是UTC格式, 可以用 Date.prototype.toUTCString()轉換,
2、Expires設定的時間是以瀏覽器本地時間作為參照的, 這樣同一條cookie在不同設備上的失效時間其實是不一樣的,
3、如果一條cookie既沒有設定Expires 也沒有設定 Max-Age, 則這條cookie變成了session cookie, 這時cookie的行為和session的類似,
4、如果同時存在 Expires 和 Max-Age, 則優先以Max-Age設定的值為準,
4、其他cookie相關
secure
1、這個屬性譯為安全,
2、當這個屬性設定為true時,此cookie只會在https和ssl等安全協議下傳輸,
3、這個屬性并不能對客戶端的cookie進行加密,不能保證絕對的安全性,
HttpOnly
如果這個屬性設定為true,就不能通過js腳本來獲取cookie的值,
關于js操作cookie
//讀取瀏覽器中的cookie
console.log(document.cookie);
//寫入cookie
document.cookie='myname=laihuamin;path=/;domain=.baidu.com';
5、localStorage
1、同一域名下會存盤相同的一段LocalStorage,
2、容量:5M(針對一個域名,同一個域名是持久存盤的),
3、只存在客戶端,默認不參與服務端的通信,
4、介面封裝,通過localStorage暴露在全域,并通過setItem和getItem等方法進行操作,方便,
5、存盤的都是字串,如果存盤物件需要JSON.stringify(),決議用JSON.parse(),
6、sessionStorage
1、容量:5M,
2、只存在客戶端,不參與服務端通信,
3、介面封裝,除了名字其他和localStorage一樣,
4、會話級別的存盤,并不是持久化的,會話結束(頁面關閉),這部分sessionStorage就不存在了,
7、indexedDB
1、運行在瀏覽器中的:非關系型資料庫,
2、鍵值對存盤,
3、異步操作,資料庫的讀寫屬于I/O操作,瀏覽器對異步I/O提供了支持,
4、受同源策略的限制,無法訪問跨域的資料庫,
8、總結
1、cookie并不適合存盤,而且存在非常多的缺陷,
2、localStorage和sessionStorage,默認不會參與和服務器的通信,
3、indexedDB為運行在瀏覽器上的非關系型資料庫,為大型資料的存盤提供了介面,
3、從輸入URL到頁面呈現發生了什么
發生三大程序分別是:網路、決議、渲染,接下來詳細從這三方面介紹,
網路
網路請求階段
1、構建請求
2、查找強快取
命中就直接使用,否則進入下一步,
3、DNS決議
DNS(域名系統),得到具體IP的程序就是DNS決議,不指定埠默認80埠
(詳細會在計算機網路篇中介紹)
4、建立TCP連接
Chrom在同一域名下要求同時最多6個TCP連接,
什么是TCP:傳輸控制協議,是一種面向連接的、可靠的、基于位元組流的傳輸層通信協議,
簡歷TCP連接經歷了下面三個階段:
一、通過三次握手建立連接
二、進行資料傳輸:
資料包校驗:接收方收到資料包后必須向發送方發送確認,如果發送方沒有收到,就判斷資料包丟失,并重新發送資料包,
優化策略:把大的資料包拆成一個個小包,依次傳輸到接收方,接收方組裝成完整資料包,
三、斷開連接,四次揮手,
(詳細會在計算機網路篇中介紹)
5、發送HTTP請求
請求頭、請求行、請求體
(詳細會在計算機網路篇中介紹)
網路回應階段
1、HTTP請求到達服務器,服務器進行對應的處理,最后要把資料傳給瀏覽器,也就是回傳網路回應,
2、回應行類似下面這樣:
HTTP/1.1 200 OK
3、回應完了就要判斷Connection欄位如果為keep-alive表示建立了持久連接,這樣TCP會一直保持,否則斷開TCP連接,請求-回應流程結束,
決議
完成了網路請求和回應,如果回應頭中Content-Type的值是text/html,那么接下來就是決議和渲染作業了,
構建DOM樹
HTML文法本質
決議演算法:1、標記化(詞法分析)2、建樹(語法分析)3、容錯機制
樣式計算
來源:1、link標簽參考,2、style標簽中的樣式,3、元素的內嵌style屬性,
1、格式化樣式表:渲染器引擎接收到CSS文本之后舊將其轉化為一個結構化物件,即:styleSheets,
2、標準化樣式屬性:有些數值并不容易被理解,在這里計算樣式之前進行標準化,
3、計算每個節點的具體樣式,
生成布局樹
1、瀏覽器的布局系統確定元素的位置,也就是要生成一棵布局樹(Layout Tree),
2、遍歷生成的 DOM 樹節點,并把他們添加到布局樹中,
3、計算布局樹節點的坐標位置,
渲染
渲染階段有四個方面:建圖層樹、生成繪制串列、生成圖塊并柵格化、顯示幕顯示內容
4、從請求一個url到請求回應和頁面渲染,有哪些可以做到性能優化的作業(優化)
減少請求次數方面
1、減少DNS路由查找,
**2、使用長連接或管道連接:**使用keep-alive或presistent來建立持久連接,持久連接降低了時延和連接建立的開銷,管道化連接在HTTP2協議中可以開啟管道化連接,即單條連接的多路復用,
3、使用CDN:(1)CDN(contentdistribute network,內容分發網路)的本質是一個快取,
(2)將資料快取在離用戶最近的地方,使用戶以最快速度獲取資料,即所謂網路訪問第一跳,
(3)由于CDN部署在網路運營商的機房,這些運營商又是終端用戶的網路服務提供商,因此用戶請求路由的第一跳就到達了CDN服務器,當CDN節點中存在瀏覽器請求的資源時,從CDN節點直接回傳給瀏覽器,最短路徑回傳回應,加快用戶訪問速度,減少資料中心負載壓力,
(4)如果該節點中請求的檔案不存在,就會向目標站獲取這個檔案,然后回傳給用戶,
(5)CDN快取的一般是靜態資源,如圖片、檔案、CSS、script腳本、靜態網頁,
**4、瀏覽器強快取:**通過設定http頭中的cache-control和expires的屬性,可設定瀏覽器快取,快取時間可以是數天,甚至是幾個月,
**5、避免重定向:**重定向之所以會比較慢,是因為它重復了域名查找,tcp鏈接,發送請求,
**6、資源合并:**合并CSS、合并javascript、合并圖片,
**7、CSS使用雪碧圖:**一次性獲取所有影像到本地,不需要每次遇到圖片就發出請求,
**8、采用懶加載:**不會在第一次渲染頁面的時候一次性請求所有的外部資源(圖片一類),只顯示用戶所能看到螢屏內的內容,
減少請求資源大小方面
**1、cookie優化:**減少cookie傳輸/減少本地cookie存盤內容的大小 ,
**2、將請求到的資源壓縮:**在服務器端對檔案進行壓縮,在瀏覽器端對檔案解壓縮,可有效減少通信傳輸的資料量,
渲染階段的優化
1、優化資源加載:
(1)資源加載的位置:
? 1、CSS放在HTML的上部,確保正常的渲染程序,瀏覽器有可能還未下載和決議到 CSS就已經開始渲染頁面從而導致了頁面呈現空白或者無格式的文本狀態,用戶體驗差,
? 2、JS放在HTML的下部,目的是防止阻塞 HTML 和 CSS 元素的加載程序,
(2)資源加載時機:
? 1、采用異步腳本加載:
<script src="example.js" async / defer></script>
? defer: 異步加載,在HTML決議完成后執行,defer的實際效果與將代碼放在body底部類似,
? async: 異步加載,加載完成后立即執行,
? 2、資源懶加載和預加載
2、關于DOM優化:
(1)快取DOM,
(2)減少DOM深度及DOM數量.
(3)避免頻繁操作DOM,(主要是為了減少重繪和回流(重繪回流在后面介紹))
3、關于JS:
(1)采用事件委托,
(2)防抖和節流(在后面介紹),
4、關于CSS:
引入CSS外部樣式表,盡可能使用link屬性,減少使用 @import 指令,
因為@import是同步操作,只有把對應的樣式匯入后,才會繼續向下執行,而link是異步的操作,
5、瀏覽器是如何渲染UI的
1、瀏覽器獲取HTML檔案,然后對檔案進行決議,形成DOM Tree,
2、與此同時,進行CSS決議,生成Style Rules,
3、接著將DOM Tree 與Style Rules合成Render Tree,
4、接著進入布局(Layout)階段,也就是為每個節點分配一個應出現在螢屏上的確切坐標,
5、隨后呼叫GPU進行繪制(Paint),遍歷Render Tree的節點,并將元素呈現出來,
6、瀏覽器如何決議css選擇器
1、瀏覽器會『從右往左』決議CSS選擇器,
2、DOM Tree與Style Rules合成為 Render Tree,實際上是將Style Rules附著到DOM Tree 上,
3、此需要根據選擇器提供的資訊對DOM Tree進行遍歷,才能將樣式附著到對應的DOM元素上,
7、DOM Tree是如何構建的
1、轉碼:瀏覽器將接收到的二進制資料按照指定編碼格式轉化為HTML字串,
2、生成Tokens:之后開始parser,瀏覽器會將HTML字串決議成Tokens,
3、構建Nodes:對Node添加特定的屬性,通過指標確定 Node 的父、子、兄弟關系和所屬 treeScope,
4、生成DOM Tree:通過node包含的指標確定的關系構建出DOM Tree,
8、前端如何實作即時通訊
1、短輪詢
短輪詢的原理很簡單,每隔一段時間客戶端就發出一個請求,去獲取服務器最新的資料,一定程度上模擬實作了即時通訊,
優點:兼容性強,實作非常簡單,
缺點:延遲性高,非常消耗請求資源,影響性能,
2、comet
1、一種是基于 AJAX 的長輪詢(long-polling)方式
優點:兼容性好,資源浪費較小,
缺點:服務器hold連接會消耗資源,回傳資料順序無保證,難于管理維護,
2、另一種是基于 Iframe 及 htmlfile 的流(streaming)方式,通常被叫做長連接,
優點:兼容性好,訊息即時到達,不發無用請求,
缺點:服務器維護長連接消耗資源,
3、SSE
Server-Sent Event,服務端推送事件,是一種允許服務端向客戶端推送新資料的HTML5技術,
優點:基于HTTP而生,因此不需要太多改造就能使用,使用方便,而websocket非常復雜,必須借助成熟的庫或框架,
缺點:基于文本傳輸效率沒有websocket高,不是嚴格的雙向通信,客戶端向服務端發送請求無法復用之前的連接,需要重新發出獨立的請求,
4、Websocket
Websocket是一個全新的、獨立的協議,基于TCP協議,與http協議兼容、卻不會融入http協議,僅僅作為html5的一部分,其作用就是在服務器和客戶端之間建立實時的雙向通信,
優點:真正意義上的實時雙向通信,性能好,低延遲,
缺點:獨立與http的協議,因此需要額外的專案改造,使用復雜度高,必須引入成熟的庫,無法兼容低版本瀏覽器,
5、Web Worker
Web Worker 的作用,就是為 JavaScript 創造多執行緒環境,允許主執行緒創建 Worker 執行緒,將一些任務分配給后者運行,
6、Service workers
Service workers 本質上充當Web應用程式與瀏覽器之間的代理服務器,也可以在網路可用時作為瀏覽器和網路間的代理,創建有效的離線體驗,
9、什么是瀏覽器的同源策略
這是一個用于隔離潛在惡意檔案的重要安全機制,
同源是指"協議+域名+埠"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源,
是以下三個標簽可以不受限制:
<img src=XXX>
<link href=XXX>
<script src=XXX>
10、跨域
1、jsonp
jsonp的具體實作請看 前端相關實作篇
優點:1、實作簡單,2、兼容性非常好
缺點:1、只支持get請求(因為
2、cors
配置:
res.header('Access-Control-Allow-Origin', 'http://example.com');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
詳細介紹:
1、瀏覽器發起cors簡單請求
(1)具體來說,就是在頭資訊之中,增加一個Origin欄位,
(2)只要同時滿足以下兩大條件,就屬于簡單請求,
? 條件1:使用下列方法之一:GET、HEAD、POST,
? 條件2:Content-Type 的值僅限于下列三者之一:text/plain、multipart/form-data、application/x-www-form-urlencoded
(3)請求中的任意 XMLHttpRequestUpload 物件均沒有注冊任何事件監聽器; XMLHttpRequestUpload 物件可以使用 XMLHttpRequest.upload 屬性訪問,
2、瀏覽器發送非簡單cors請求
(1)非簡單請求是那種對服務器有特殊要求的請求,
(2)比如請求方法是PUT或DELETE,或者Content-Type欄位的型別是application/json
3、發起非簡單請求有如下步驟
(1)預檢請求
? 非簡單請求的CORS請求,會在正式通信之前,增加一次HTTP查詢請求,稱為"預檢"請求(preflight),
? 當前網頁所在的域名是否在服務器的許可名單之中,以及可以使用哪些HTTP動詞和頭資訊欄位,
? 只有得到肯定答復,瀏覽器才會發出正式的XMLHttpRequest請求,否則就報錯,
? "預檢"請求用的請求方法是OPTIONS,表示這個請求是用來詢問服務器支持什么請求方法的
? Access-Control-Request-Method:該欄位是必須的,用來列出瀏覽器的CORS請求會用到哪些HTTP方法,
? Access-Control-Request-Headers:該欄位是一個逗號分隔的字串,指定瀏覽器CORS請求會額外發送的頭資訊欄位,
(2)瀏覽器的正常請求和回應
一旦服務器通過了"預檢"請求,以后每次瀏覽器正常的CORS請求,就都跟簡單請求一樣,
會有一個Origin頭資訊欄位,服務器的回應,也都會有一個Access-Control-Allow-Origin頭資訊欄位,
4、其他:
XMLHttpRequest物件的getResponseHeader()方法只能拿到6個基本欄位:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,
瀏覽器發送CORS請求是默認不發送Cookie和HTTP認證資訊,
配置:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
JSONP只支持GET請求,CORS支持所有型別的HTTP請求,JSONP的優勢在于支持老式瀏覽器,以及可以向不支持CORS的網站請求資料,
3、中間代理
一般通過nginx進行的中間代理,
nginx是一款極其強大的web服務器,其優點就是輕量級、啟動快、高并發,
現在的新專案中nginx幾乎是首選,我們用node或者java開發的服務通常都需要經過nginx的反向代理,
4、其他跨域方案
1、HTML5 XMLHttpRequest 有一個API,postMessage()方法允許來自不同源的腳本采用異步方式進行有限的通信,可以實作跨文本檔、多視窗、跨域訊息傳遞,
2、WebSocket 是一種雙向通信協議,在建立連接之后,WebSocket 的 server 與 client 都能主動向對方發送或接收資料,連接建立好了之后 client 與 server 之間的雙向通信就與 HTTP 無關了,因此可以跨域,
3、window.name + iframe:window.name屬性值在不同的頁面(甚至不同域名)加載后依舊存在,并且可以支持非常長的 name 值(2M),我們可以利用這個特點進行跨域,
4、location.hash + iframe:a.html欲與c.html跨域相互通信,通過中間頁b.html來實作, 三個頁面,不同域之間利用iframe的location.hash傳值,相同域之間直接js訪問來通信,
5、document.domain + iframe: 該方式只能用于二級域名相同的情況下,比如 a.test.com 和 b.test.com 適用于該方式,我們只需要給頁面添加 document.domain =‘test.com’ 表示二級域名都相同就可以實作跨域,兩個頁面都通過js強制設定document.domain為基礎主域,就實作了同域,
5、附加介紹WebSocket
1、建立在 TCP 協議之上,它需要通過握手連接之后才能通信,服務器端的實作比較容易,
2、與 HTTP 協議有著良好的兼容性,默認埠也是80或443, (并且握手階段采用 HTTP 協議)
,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務器,
3、WebSocket的通信建立——握手程序,WebSocket的握手使用HTTP來實作,客戶端發送帶有Upgrade頭的HTTP Request訊息,
Connection: Upgrade
Upgrade: websocket
HTTP1.1與WebSocket的異同
相同點:
(1)都是基于TCP的應用層協議,
(2)都使用Request/Response模型進行連接的建立,
(3)在連接的建立程序中對錯誤的處理方式相同,在這個階段WebSocket可能回傳和HTTP相同的回傳碼,
不同點:
(1)HTTP協議基于Request/Response,只能做單向傳輸,是半雙工協議,而WebSocket是全雙工協議,類似于Socket通信,雙方都可以在任何時刻向另一方發送資料,
(2)WebSocket使用HTTP來建立連接,但是定義了一系列新的Header域,這些域在HTTP中并不會使用,換言之,二者的請求頭不同,
(3)WebSocket的連接不能通過中間人來轉發,它必須是一個直接連接,如果通過代理轉發,一個代理要承受如此多的WebSocket連接不釋放,就類似于一次DDOS攻擊了,
(4)WebSocket在建立握手連接時,資料是通過HTTP協議傳輸的,但在建立連接之后,真正的資料傳輸階段是不需要HTTP協議參與的,
(5)WebSocket傳輸的資料是二進制流,是以幀為單位的,HTTP傳輸的是明文傳輸,是字串傳輸,WebSocket的資料幀有序,
HTTP的長連接與WebSocket的持久連接的異同
HTTP1.1的連接默認使用長連接(Persistent connection),
“長輪詢”:即客戶端發送一個超時時間很長的Request,服務器保持住這個連接,在有新資料到達時回傳Response,
WebSocket的持久連接:只需建立一次Request/Response訊息對,之后都是TCP連接,避免了需要多次建立Request/Response訊息對而產生的冗余頭部資訊,節省了大量流量和服務器資源,因此被廣泛應用于線上WEB游戲和線上聊天室的開發,
11、常見的瀏覽器兼容性解決方案
1、不同瀏覽器的標簽默認的margin和padding不同
解決方案:CSS里 *{margin:0;padding:0;}
備注:這個是最常見的也是最易解決的一個瀏覽器兼容性問題,幾乎所有的CSS檔案開頭都會用通配符*來設定各個標簽的內外補丁是0,
2、圖片默認有間距,使用float屬性為img布局
3、標簽最低高度設定min-height不兼容,
如果我們要設定一個標簽的最小高度200px,需要進行的設定為:{min-height:200px; height:auto !important; height:200px; overflow:visible;},
4、塊屬性標簽float后,又有橫行的margin情況下,在IE6顯示margin比設定的大,
解決方案:在float的標簽樣式控制中加入 display:inline;將其轉化為行內屬性,
5、設定較小高度標簽(一般小于10px),在IE6,IE7,遨游中高度超出自己設定高度 (IE6、7和遨游里這個標簽的高度不受控制,超出自己設定的高度),
解決方案:給超出高度的標簽設定overflow:hidden;或者設定行高line-height 小于你設定的高度,
6、行內屬性標簽,設定display:block后采用float布局,又有橫行的margin的情況,IE6間距bug,
解決方案:在display:block;后面加入display:inline;display:table;
12、瀏覽器內多個標簽頁之間的通信
1、localStorage
標簽頁呼叫localStorage.setItem(name,val)保存資料localStorage.removeItem(name)洗掉資料的時候會觸發 'storage’事件,
另外一個標簽頁監聽document物件的storage事件,在事件event物件屬性中獲取資訊,
window.addEventListener("storage", function(event){
console.log(event.key + "=" + event.newValue);
});
2、cookie
在A頁面將需要傳遞的訊息存盤在cookie當中,
在B頁面設定setInterval,以一定的時間間隔去讀取cookie的值,
(不同域需要進行降域處理)
3、WebSocket、SharedWorker
13、瀏覽器同域名請求的最大并發數限制
一般限制在8個以內吧
Chrome同域名下資源加載的最大并發連接數為6
14、CDN
什么是 CDN:中文名叫做「內容分發網路」,它的作用是減少傳播時延,找最近的節點,
CDN 的優點:1、訪問加速,2、減輕源站(服務器)負載,3、抗住攻擊,
應用:
1、最常見的應用,就是用于前端靜態資源的加速
2、快取設定: s-maxage,我們可以把 max-age 用于本地快取,把 s-maxage 用于 CDN 快取時間,避免臟資料的產生,
3、快取命中率,
4、判斷是否命中快取,
5、資源預熱,
6、Vary,
7、Range,
8、無私鑰 HTTPS,
15、如何判斷網頁加載完成了
window. document.readyState == "complete"
document.addEventListener("readystatechange", function (e) {
if (e.target.readyState === 'complete') {
console.log("加載完成");
} else {
console.log("正在加載");
}
})
16、懶加載和預加載
1、懶加載
懶加載也就是延遲加載,
優點:頁面加載速度快、可以減輕服務器的壓力、節約了流量,用戶體驗好,
2、預加載
預加載的核心要點如下:
1.圖片等靜態資源在使用之前的提前請求;
2.資源后續使用時可以從快取中加載,提升用戶體驗;
3.頁面展示的依賴關系維護(必需的資源加載完才可以展示頁面,防止白屏等);
實作預加載主要有三個方法:
1.html中img標簽最初設定為display:none;
2.js腳本中使用image物件動態創建好圖片;
3.使用XMLHttpRequest物件可以更加精細的控制預加載程序,缺點是無法跨域:
提前加載圖片,當用戶需要查看時可直接從本地快取中渲染,
意義:預加載可以說是犧牲服務器前端性能,換取更好的用戶體驗,這樣可以使用戶的操作得到最快的反映,
17、Session、Cookie、Token、Json Web Toekns(JWT)
1、Cookie 和 Session
2、JWT 和 Session Cookies 的相同之處
3、什么是 Session Cookies
4、JSON Web Token
5、JWT 和 Session Cookies 的不同
18、實作圖片懶加載
方案一:clientHeight、scrollTop 和 offsetTop,
方案二:getBoundingClientRect,
方案三: IntersectionObserver,
19、防抖節流
這里簡單闡述概念,為了第四點優化的解釋,具體代碼實作請看 前端相關實作篇,
1、防抖
一段時間內不論多少次點擊都被忽略當持續觸發某個事件時,會有規律的每隔時間n就執行一次函式(一段時間內只執行一次),
應用:
1、滑鼠不斷觸發單位時間內只執行一次,
2、window觸發resize的時候,
2、節流
指的是在時間n內,函式被觸發多次,但只執行一次新的觸發,也就在時間n內,碰到新的觸發,就清除之前的,重新計時(每次新的觸發就重新記時),
應用:
1、search搜索,
2、頻繁點贊和取消點贊,
20、重繪和回流
重繪不一定導致回流,但回流一定會發生重繪
渲染行程中的主執行緒(回流會全部從新執行):生成DOM樹、計算樣式、生成布局樹、建圖層樹、繪制串列
1、重繪
觸發條件:當DOM的修改導致了樣式的變化,并且沒有影響幾何屬性的時候,會導致重繪,
計算樣式和繪制串列(中間會跳過生成布局樹和建立圖層樹)
2、回流(重排)
觸發條件:當我們對DOM結構的修改引發DOM幾何尺寸變化的時候,會發生回流的程序
(1)一個DOM元素的幾何變化,常見的集合屬性有width、height、padding、margin、left、top、border ,
(2)使DOM節點發生增級訓者移動 ,
(3)讀寫offset族、scroll族和client族屬性的時候,瀏覽器為了獲取這些值,需要進行回流的操作,
(4)呼叫window.getComputedStyle方法,
3、合成
利用CSS3的transform、opacity、filter這些屬性可以實作合成的效果,也就是大家常說的GPU加速,
GPU加速的原因:在合成的情況下,會之間跳過布局和繪制流程,之間進入非主執行緒處理部分,即直接交給合成執行緒處理,
能充分發揮GPU的優勢,合成執行緒在生成位圖的程序中會呼叫執行緒池,并在其中使用GPU進行加速,而GPU是擅長處理位圖資料的,
沒有占用主執行緒的資源,即使主執行緒卡住了,效果依然能夠流暢的展示,
4、開發注意
1、避免頻繁使用style,而是采用class的方式,
2、使用createDocumentFragment進行批量的 DOM 操作,
3、對于 resize、scroll 等進行防抖/節流處理,
4、添加 will-change: tranform ,讓渲染引擎為其單獨實作一個圖層,當這些變換發生時,僅僅只是利用合成執行緒去處理這些變換,而不牽扯到主執行緒,大大提高渲染效率,當然這個變化不限于tranform, 任何可以實作合成效果的 CSS 屬性都能用will-change來宣告,
5、如何避免重繪和回流
1、集中改變樣式:我們往往通過改變class的方式來集中改變樣式,
2、使用DocumentFragment:我們可以通過createDocumentFragment創建一個游離于DOM樹之外的節點,然后在此節點上批量操作,最后插入DOM樹中,因此只觸發一次重排
3、提升為合成層: will-change: transform;
21、XSS攻擊
1、什么是XSS攻擊
XSS 全稱是 Cross Site Scripting(即跨站腳本),為了和 CSS 區分,故叫它XSS,
XSS 攻擊是指瀏覽器中執行惡意腳本(無論是跨域還是同域),從而拿到用戶的資訊并進行操作,
2、攻擊完成的事情
(1)竊取Cookie,
(2)監聽用戶行為,比如輸入賬號密碼后直接發送到黑客服務器,
(3)修改DOM偽造登陸表單,
(4)在頁面生成浮窗廣告,
3、XSS攻擊的實作三種方式
存盤型:將惡意的腳本存盤起來,存盤型的XSS將腳本存盤到服務端的資料庫,然后再客戶端執行這些腳本,從而達到攻擊效果,
常見的場景就是留言區提交腳本,前后端沒有做好轉義作業,
反射型:指的是惡意腳本作為網路請求的一部分,
比如:
http://sanyuan.com?q=<script>alert("你完蛋了")</script>
之所以叫它反射型, 是因為惡意腳本是通過作為網路請求的引數,經過服務器,然后再反射到HTML檔案中,執行決議,
檔案型:
檔案型的 XSS 攻擊并不會經過服務端,而是作為中間人的角色,在資料傳輸程序劫持到網路資料包,然后修改里面的 html 檔案,
這樣的劫持方式包括WIFI路由器劫持或者本地惡意軟體等,
4、防范措施
1、無論是在前端和服務端,都要對用戶的輸入進行轉碼或者過濾,
**2、利用 CSP:**核心思想就是服務器決定瀏覽器加載哪些資源,
? 核心思想就是服務器決定瀏覽器加載哪些資源,
? 限制其他域下的資源加載,
? 禁止向其它域提交資料,
? 提供上報機制,能幫助我們及時發現 XSS 攻擊,
**3、利用 HttpOnly:**很多 XSS 攻擊腳本都是用來竊取Cookie, 而設定 Cookie 的 HttpOnly 屬性后(為true),JavaScript 便無法讀取 Cookie 的值,這樣也能很好的防范 XSS 攻擊,
22、CSRF攻擊
1、什么是CSRF攻擊
CSRF(Cross-site request forgery), 即跨站請求偽造,
指的是黑客誘導用戶點擊鏈接,打開黑客的網站,然后黑客利用用戶目前的登錄狀態發起跨站請求
2、攻擊完成的事(點擊黑客連接后)
1、自動發 GET 請求,
黑客網頁里面可能有一段這樣的代碼:
<img src="https://xxx.com/info?user=hhh&count=100">
進入頁面后自動發送 get 請求,值得注意的是,這個請求會自動帶上關于 xxx.com 的 cookie 資訊(這里是假定你已經在 xxx.com 中登錄過),
如果服務器沒有驗證機制,它可能認為請求是一個正常用戶,因為攜帶了cookie,所以就可以進行相應的操作,比如轉賬,
2、自動發 POST 請求,
可能是一個表單資訊,同樣攜帶cookie,讓服務器誤以為是一個正常的用戶在操作,
3、誘導點擊發送 GET 請求,
點擊后,自動發送 get 請求,接下來和自動發 GET 請求部分同理,
3、防范措施
1、利用Cookie的SameSite屬性
原理:
CSRF攻擊中重要的一環就是自動發送目標站點下的 Cookie,Cookie 模擬了用戶的身份,
在 Cookie 當中有一個關鍵的欄位,可以對請求中 Cookie 的攜帶作一些限制這個欄位就是SameSite,
SameSite可以設定為三個值,Strict、Lax和None,(谷歌新版本更新有這個問題2020年吧好像),
在Strict模式下,瀏覽器完全禁止第三方請求攜帶Cookie,比如請求sanyuan.com網站只能在sanyuan.com域名當中請求才能攜帶 Cookie,在其他網站請求都不能,
在Lax模式,就寬松一點了,但是只能在 get 方法提交表單況或者a 標簽發送 get 請求的情況下可以攜帶 Cookie,其他情況均不能,
在None模式下,也就是默認模式,請求會自動攜帶上 Cookie,
2、驗證來源站點
需要要用到請求頭中的兩個欄位: Origin和Referer,
Origin只包含域名資訊,而Referer包含了具體的 URL 路徑
這兩者都是可以偽造的,通過 Ajax 中自定義請求頭即可,安全性略差,
3、CSRF Token
瀏覽器向服務器發送請求時,服務器生成一個字串,將其植入到回傳的頁面中,
然后瀏覽器如果要發送請求,就必須帶上這個字串,然后服務器來驗證是否合法,如果不合法則不予回應,
4、總結對比
CSRF 攻擊并不需要將惡意代碼注入用戶當前頁面的html檔案中,而是跳轉到新的頁面,
利用服務器的驗證漏洞和用戶之前的登錄狀態來模擬用戶進行操作,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/262052.html
標籤:其他
上一篇:eclipse匯入web專案出現錯誤求大神解答 'Launching Bootstrap' has encountered aprob
下一篇:微信瀏覽器中實作音樂自動播放
