前端面試準備---瀏覽器和網路篇(一)
本文主要內容:
AJAX
GET和POST請求的區別
同源策略、JSONP、跨域方式
瀏覽器架構
輸入一個Url到載入網頁的全過程,發生了什麼?
瀏覽器渲染的步驟
重繪和迴流
頁面渲染最佳化
AJAX
什麼是AJAX?
AJAX即一種非同步請求,可以實現頁面區域性重新整理;
AJAX實現的步驟:
建立請求物件
與服務端建立連線,執行open方法;
傳送請求,執行send方法;
為請求物件繫結onreadystate事件,當readyState為4 且 status為200時處理資料;
AJAX封裝
function
Ajax
(
options
)
{
var
xhr
=
null
;
var
params
=
formsParams
(
options
。
data
);
// 第一步: 建立請求物件
if
(
window
。
XMLHttpRequest
)
{
xhr
=
new
XMLHttpRequest
();
}
else
{
// 相容IE6
xhr
=
new
ActiveXObject
(
“Microsoft。XMLHTTP”
);
}
// 第二步: 連線,執行open和send方法;
if
(
options
。
type
==
‘GET’
)
{
xhr
。
open
(
options
。
type
,
options
。
url
+
‘?’
+
params
,
options
。
async
);
xhr
。
send
();
}
else
if
(
options
。
type
==
‘POST’
)
{
xhr
。
open
(
options
。
type
,
options
。
url
,
options
。
async
);
xhr
。
setRequestHeader
(
‘Content-Type’
,
‘application/x-www-form-urlencoded’
);
xhr
。
send
(
params
);
}
// 繫結onreadystatechange事件
xhr
。
onreadystatechange
=
function
()
{
if
(
xhr
。
readyState
==
4
&&
xhr
。
status
==
200
)
{
options
。
success
(
xhr
。
responseText
);
}
}
function
formsParams
(
data
)
{
var
arr
=
[];
for
(
var
i
in
data
)
{
arr
。
push
(
i
+
‘=’
+
data
[
i
]);
}
arr
。
join
(
‘&’
);
}
}
使用方法:
Ajax
({
type
:
‘GET’
,
url
:
‘a。php’
,
async
:
true
,
data
:
{
name
:
‘zhangsan’
,
age
:
10
},
success
:
function
(
data
)
{
console
。
log
(
data
);
}
});
AJAX的優缺點:
優點:
實現區域性重新整理
減輕伺服器端壓力
缺點:
破壞瀏覽器前進和後退機制;
一個頁面ajax請求過多,會造成頁面載入緩慢;
資料安全問題不太好,可以採用資料加密的方式;
readyState狀態碼:
0 - open方法還沒呼叫
1 - 已經呼叫send方法,正在傳送請求
2 - send方法已經完成,已經接收到全部相應內容
3- 正在解析相應內容
4 - 相應內容解析完成
staus狀態碼:
200 - 成功
404 - 未找到
5** - 伺服器錯誤
GET和POST請求的區別
GET和POST是HTTP請求的兩種方式;
區別要點:
get: 快取/長度受限(2M)/無副作用(不修改資源)/冪等的場景(請求資料與資源無關)
post: 安全/長度無限制/支援更多編碼型別(ACII & 二進位制)
關於安全方面,其實GET和POST兩者都不安全。
雖然POST請求的資料不攜帶在URL上,但是因為HTTP在網路傳輸的時候是明文傳輸的,所以,只要使用抓包工具,能輕而易舉的獲取資料;
想要安全傳輸,只有加密,可以前端將傳輸引數進行加密,也可以才用HTTPS;
區別見下圖
,來源W3school
同源策略、JSONP、跨域方式
含義:
埠號、域名、協議名,三者必須全部相同才符合同源策略,反之即為跨域;
JSONP
原理:動態生成script標籤,利用script不受跨域的限制,但是缺點是隻支援get請求;
封裝JSONP方法:
function
jsonp
(
url
,
callback
,
success
)
{
var
script
=
document
。
createElement
(
‘script’
);
script
。
src
=
url
;
script
。
async
=
true
;
script
。
type
=
‘text/javascript’
;
window
[
callback
]
=
function
(
data
)
{
success
&&
success
(
data
);
}
document
。
body
。
appendChild
(
script
);
}
跨域的其他方法
設定 CORS: Access-Control-Allow-Origin:*
2。 postMessage
3。 WebSocket
4。 iframe
瀏覽器架構
先解釋一個概念:
執行緒(Thread):執行緒是程序的一部分,並且執行程序中的一部分程式;
程序 (Process):啟動一個程式,就會建立一個程序,作業系統為其分配記憶體,程序中的所有執行緒中的所有程式狀態都儲存到該記憶體中,關閉程式,程序也會消失,記憶體會釋放;
下面這個圖很形象:
不同瀏覽器中的架構不同:
可能是一個有很多執行緒的程序
也可能是有少量執行緒的多個程序,透過IPC進行通訊
Chrome 就是屬於多程序之間進行通訊,現在是為每個標籤建立一個程序,正在嘗試為每個站點提供自己的程序;
多程序的好處
多程序的設計可以使多個標籤頁面的載入不受其他的影響;
安全性和沙盒,每個程序有自己獨立的儲存空間
Chrome瀏覽器的一些機制
由於每個程序都有自己的儲存空間,它通常包含公共基礎結構的副本(例如V8引擎),這樣會消耗很多記憶體空間;
Chrome瀏覽器為了節省記憶體,對程序的數量做了限制,這個因記憶體和CPU功率而定;
當達到這個限制的時候,瀏覽器會在同一程序中執行從同一站點開啟的多個選項卡;
2。 當Chrome瀏覽器遇到更強大的硬體時,會將每個服務拆分成不同的程序,從而提供更高的穩定性;但是如果資源有限的裝置上,會將服務整合到一個程序中,從而節省記憶體。Android上已經實現了服務的整合;
瀏覽器的組成
使用者介面(User Interface)
瀏覽器引擎(browser engine)
渲染引擎(rendering engine)
網路(Networking)
使用者介面後段(UI Backend)
JavaScript解析器(JavaScript Interpreter)
資料儲存(Data persistence)
下圖形象的展示了瀏覽器的組成:
輸入一個Url到載入網頁的全過程,發生了什麼?
域名解析:瀏覽器將URL解析出相對應的伺服器的IP地址(現在本地瀏覽器的DNS快取中查詢,沒有的話,再向瀏覽器預設的DNS伺服器傳送查詢請求,同時快取),並從url中解析出埠號
瀏覽器與目標伺服器建立一條TCP連線(三次握手);
瀏覽器向伺服器傳送一條HTTP請求報文
伺服器返回給瀏覽器一條HTTP響應報文
關閉連線,解析文件
瀏覽器進行渲染
如果文件中資源載入就再次建立連線,直至資源全部載入完畢
瀏覽器渲染的步驟
HTML解析出DOM Tree
CSS解析出Style Rules
兩者關聯生成Render Tree
Layout(佈局)根據Render Tree 計算每個節點的資訊
Painting 根據計算好的資訊進行渲染整個頁面
瀏覽器解析文件的過程中,
如果遇到script標籤,會立即解析指令碼,停止解析文件(因為JS可能會改變DOM和CSS,如果繼續解析會造成浪費)。
如果是外部script, 會等待指令碼下載完成之後在繼續解析文件。現在script標籤增加了defer和async屬性,指令碼解析會將指令碼中改變DOM和css的地方解析出來,追加到DOM Tree 和 Style Rules上
重繪和迴流
迴流(reflow):當頁面發生重新佈局的過程。元素的幾何尺寸發生變化時,需要重新計算節點資訊,也就是執行了渲染步驟的第4步;
重繪(repaint):螢幕的一部分需要重新繪製,比如css背影色變化,顏色變化等。
迴流比重繪成本高的多得多;
舉例說明
$
(
‘body’
)。
css
(
‘color’
,
‘red’
);
// repaint
$
(
‘body’
)。
css
(
‘margin’
,
‘2px’
);
// reflow, repaint
var
bstyle
=
document
。
body
。
style
;
// cache
bstyle
。
padding
=
“20px”
;
// reflow, repaint
bstyle
。
border
=
“10px solid red”
;
// 再一次的 reflow 和 repaint
bstyle
。
color
=
“blue”
;
// repaint
bstyle
。
backgroundColor
=
“#fad”
;
// repaint
bstyle
。
fontSize
=
“2em”
;
// reflow, repaint
// new DOM element - reflow, repaint
document
。
body
。
appendChild
(
document
。
createTextNode
(
‘dude!’
));
但是瀏覽器不會像上邊那樣,每改一次樣式都會重新reflow和repaint一次。一般來說,瀏覽器會把這樣的操作積攢一波,然後reflow一次。
頁面渲染最佳化
基於對渲染過程的瞭解,推薦一下最佳化:
HTML文件結構層次儘量少,最好不深於6層
指令碼儘量放後邊,避免組織頁面載入
少量首屏樣式可以放在便籤內
樣式結構層次儘量簡單
指令碼減少DOM操作,減少迴流,儘量快取訪問DOM的樣式資訊
儘量減少JS修改樣式,可以透過修改class名的方式解決
減少DOM查詢,快取DOM查詢結果
動畫在螢幕外或頁面滾動時,儘量停止