1. TCP和UDP的區別
\ | TCP | UDP |
---|---|---|
是否連接 | 面向連接 | 無連接 |
是否可靠 | 可靠 | 不可靠 |
連接對象個數 | 1對1 | 1對1 或1 對多 |
傳輸方式 | 面向字節 | 面向報文 |
首部開銷 | 20字節 | 8字節 |
使用場景 | 可靠傳輸,如: 文件傳輸 | 實時應用(IP電話、視頻會議、直播等) |
2. WebSocket
(1)什么是WebSocket?
WebSocket是HTML5中的協議,支持持舊連接,http協議不支持持久性連接.http1.0和http1.1都不支持持久性的連接,http1.1中的keep-alive,將多個http請求合并為1個
(2)WebSocket是什么樣的協議,具有什么優點?
HTTP的聲明周期通過Request來界定,也就是: 一個Request對應一個Response
- 在http1.0中,一個一個Request和一個Response之后,這次HTTP請求就結束了
- 在http1.1中,有一個
connection: Keep-alive
, 表示在一次HTTP連接中,可以發送多個Request和接收多個Response(注意一個Request對應一個Response)
WebSocket是基于HTTP協議的,請求的基本格式如下:
GET / chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
多出了下面2個屬性:
Upgrade: webSocket
Connection: Upgrade
告訴服務器發送的是websocket
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
(3)WebSocket 教程
為什么需要WebSocket?
- 初次接觸WebSocket的,都會問同樣的問題: 我們已經有了HTTP協議,為什么還需要另一個協議? 它能帶來什么好處?
- 因為HTTP協議有一個缺陷: 通常只能由客戶端發起
- 服務器做不到主動向客戶端推送信息
- 這種單向請求的特點,注定了如果服務器有連續的狀態變化,客戶端要獲知就非常麻煩。我們只能用"輪詢":每隔一段時間,就發一個詢問,了解服務器有沒有最新的信息(典型的場景就是聊天室)
- 輪詢的效率非常低,于是WebSocket就是這樣誕生了
WebSocket協議的特點
WebSocket協議在2008年誕生,2011年成為國際標準.所有瀏覽器都已經支持了
它最大的特點就是,服務器可以主動向客戶端推送信息,客戶端也可以主動向服務器發送信息
其他特點包括:
(1)建立在TCP協議之上,服務端的實現比較容易
(2)與HTTP協議有著良好的兼容性。默認端口也是80和443,并且握手階段采用HTTP協議,因此握手時不容易屏蔽,能通過各種HTTP代理服務器
(3)數據格式比較輕量,性能開銷小,通信高效
(4)可以發送文本,也可以發送二進制數據
(5)沒有同源限制,客戶端可以與任意服務器通信
(6)協議標識符是ws
ws://example.com:80/some/path
客戶端簡單示例
var ws = new WebSocket("wss://echo.websocket.org");ws.open = function(evt){console.log('Connection open')ws.send('Hello WebSockets!')
};ws.onmessage = function(evt) {console.log('Received Message: ' + evt.data);ws.close()
}ws.onclose = function(evt) {console.log('Connection closed')
}
3. 幾個很實用的BOM屬性對象方法
- 什么是BOM: Bom是瀏覽器對象,
1.location
值 | 含義 |
---|---|
location.href | 返回或設置當前文檔的URL |
location.search | 返回URL中的查詢字符串部分 |
location.hash | 返回URL#后面的內容 |
location.host | 返回URL中的域名部分 |
location.hostname | 返回URL中的主域名部分 |
location.pathname | 返回URL中的域名后的部分 |
location.port | 返回URL中的端口部分 |
location.protocol | 返回URL中的協議部分 |
location.assign | 設置當前的文檔 |
location.replace() | 設置當前文檔的URL,并且在history對象的地址列表中移除這個URL location.replace(url) |
location.reload() | 重載當前頁面 |
2.history對象
值 | 含義 |
---|---|
history.go() | 前進或后退指定的頁面數 |
history.back() | 后退一頁 |
history.forward() | 前進一頁 |
3. Navigator對象
值 | 含義 |
---|---|
navigator.userAgent | 返回用戶代理頭的字符串表示 |
navigator.cookieEnabled | 返回瀏覽器是否支持cookie |
4. 說一下HTML drag api
值 | 含義 |
---|---|
dragstart | 事件主體是被拖放元素,在開始拖放元素時觸發 |
drag | 事件主體是拖放元素,在正在被拖放元素時觸發 |
dragenter | 事件主體是目標元素,在被拖放元素進入某元素時觸發 |
dragover | 事件主體是目標元素,在被拖放在某元素內移動時觸發 |
dragleave | 事件主體是目標元素,在被拖放元素移出目標元素時觸發 |
drop | 事件主體是目標元素,在目標元素完全接受被拖放元素時觸發 |
dragend | 事件主體是被拖放元素,在整個拖放操作結束時觸發 |
【小栗子】: 將本地圖片拖放至瀏覽器中
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>拖動一張圖片到瀏覽器中來</title><style>body{text-align: center;}#container{border: 1px solid #aaa;border-radius: 3px;padding: 10px;margin: 10px;min-height: 400px;}</style></head><body><h1>拖放API的擴展知識</h1><h3>請拖動您的照片到下方方框區域</h3><div id="container"></div></body><script>var container = document.getElementById('container');document.ondragover = function(e){e.preventDefault()}document.ondrop = function(e){e.preventDefault()}container.ondragover = function(e){e.preventDefault()}container.ondrop = function(e){var paper = e.dataTransfer.files[0];var file = new FileReader();file.readAsDataURL(paper)file.onload = function(){console.log('文件讀取完成')console.log(file.result);var img = new Image();img.src = file.result;container.appendChild(img)}}</script>
</html>
5. http2.0
- 參考
5.1 HTTP的歷史
- 早在HTTP建立之初,主要是為了將超文本標記語言(HTML)從Web服務器傳送到客戶端的瀏覽器
- 對于前端來說,我們寫好的HTML頁面是放在web服務器上的,用戶通過瀏覽器訪問URL來獲取網頁的顯示內容
- 但是到了WEB2.0以來,我們的頁面變得復雜,不僅僅單純的是一些簡單的文字和圖片,同時我們的HTML頁面有了CSS,JavaScript,來豐富我們的頁面展示
- 當ajax的出現,我們又多了一種向服務器端獲取數據的方法,這些其實都是基于HTTP協議的.
- 同樣到了移動互聯網時代,我們頁面可以跑在手機端瀏覽器里面,但是和PC端相比,手機端的網絡情況更加復雜,這使得我們不得不對HTTP進行深入理解并不斷優化
5.2 HTTP的基本優化
影響一個HTTP網絡請求的因素主要有兩個: 帶寬和延遲
- 帶寬: 現在互聯網基礎設施已經使得帶寬極大的提升,我們不再會擔心由帶寬而影響網速
- 延遲:
- 瀏覽器阻塞(HOL blocking): 瀏覽器會因為一些原因阻塞請求.瀏覽器對于同一個域名,同時只能有4個連接,超過瀏覽器最大連接數限制,后續請求將會被阻塞
- DNS查詢(DNS Lookup): 瀏覽器需要知道目標服務器的IP才能建立連接.將域名解析為IP的這個系統就是DNS.這個通常可以利用DNS緩存來達到減少這個時間的目的
- 建立連接(initial connection): HTTP是基于TCP協議的,瀏覽器最快也要在三次握手時才能捎帶HTTP請求報文,達到真正的建立連接,但是這些連接無法復用會導致每次請求都經歷三次握手和慢啟動.三次握手在高延遲下影響較明顯,慢啟動則對文件類大請求影響較大
5.3 HTTP1.0和HTTP1.1的一些區別
- 緩存處理,在HTTP/1.0中主要使用header里的
if-modified-since, exprires
來為緩存判斷標準,HTTP/1.1則引入了更多的緩存控制策略例如Entity tag, if-unmodified-since, if-match, if-none-match
等更多可供選擇的緩存來控制緩存策略 - 帶寬優化及網絡連接的使用,在HTTP/1.0中,存在一些浪費帶寬的現象,例如客戶端只是需要某個對象的一部分,而服務器卻將整個對象送過來了,并且不支持斷點續傳功能,HTTP1.1則在請求頭引入了range頭域,它允許只請求資源的某個部分,即返回碼是206(Partial Content),這樣就方便了開發者自由的選擇以便于充分利用帶寬和連接
- 錯誤通知的管理,在HTTP/1.1中新增了24個錯誤狀態響應碼,如406(Confict)表示請求的資源與資源的當前狀態發生沖突; 410(Gone)表示服務器上的某個資源被永久性的刪除
- Host頭處理,在HTTP/1.0中認為每臺服務器都綁定一個唯一的IP地址,因此,請求消息中的URL并沒有傳遞主機名(hostname).但隨虛擬主機技術的發展,在一臺物理服務器上可以存在多個虛擬主機(Muti-homed Web Server),并且它們共享一個IP地址。HTTP/1.1的請求消息和響應消息都應支持Host頭域,且請求消息中沒有Host頭域會報告一個錯誤(400 Bad Request)
- 長連接,HTTP/1.1 支持長連接(PersistentConnection)和請求的流水線(Pipelining)處理,在一個TCP連接上可以傳送多個HTTP請求和響應,減少了建立和關閉連接的消耗和延遲,在HTTP/1.1中默認開啟
Connection: keep-alive
,一定程度上彌補了HTTP/1.0每次請求都要創建連接的缺點
5.4 HTTPS與HTTP的區別
- HTTPS協議需要到CA申請證書,一般免費證書很少,需要繳費
- HTTP協議運行在TCP之上,所有傳輸的內容都是明文,HTTPS運行在SSL/TLS之上,SSL/TLS運行在TCP之上,所有傳輸的內容都經過加密的
- HTTP和HTTPS使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443
- HTTPS可以有效的防止運營商劫持,解決劫持的一大問題
graph LRsubgraph HTTPa1(HTTP) --> a2(TCP)endsubgraph HTTPSs1(HTTP) --> s2(SSL/TLS)s2 --> s3(TCP)end
5.5 SPDY: HTTP/1.x 的優化
2012年google如一聲驚雷提出了SPDY的方案,優化了HTTP/1.X的請求延遲,解決了HTTP/1.X的安全性問題:
- 降低延遲,針對HTTP高延遲的問題,SPDY優雅的采用了多路復用(multiplexing).多路復用通過多個請求stream共享一個tcp的連接方式,解決了瀏覽器阻塞(HOL blocking)的問題,降低了延遲同時提高了帶寬利用率
- 請求優先級(request priorization).多路復用帶來了一個新的問題是,在連接共享基礎之上有可能會導致關鍵連接被阻塞。SPDY允許給每個request設置優先級,這樣重要的請求就會優先得到響應.比如瀏覽器加載首頁,首頁的html內容應該優先展示,之后才是各種靜態資源文件,腳本文件等加載,這樣可以保證用戶能第一時間看到頁面內容
- header壓縮.選擇了合適的算法較少包的大小和數量
- 基于HTTPS的加密協議傳輸,大大提高了傳輸數據的可靠性
- 服務器推送(server push),采取了SPDY的網頁,例如我的網頁有一個style.css的請求,在客戶端收到style.css的時候,服務器會將style.js的文件推送給客戶端.當客戶端再次嘗試獲取style.js時就可以直接從緩存中獲取到,不用再發請求了.
5.6 HTTP/2.0
HTTP/2.0 可以說是SPDY的升級版(基于SPDY設計的),但是HTTP/2.0跟SPDY也有不同的地方,如下:
- HTTP/2.0 支持明文HTTP傳輸,而SPDY強制使用HTTPS
- HTTP/2.0 消息頭的壓縮算法采用HPACK,而非SPDY采用的DEFLATE
5.7 HTTP/2.0 和 HTTP/1.x 相比的新特性
- 新的二進制格式(Binary Format),HTTP/1.x 的解析是基于文本。基于文本協議的格式解析存在天然缺陷,文本的表現形式有多樣性,要做到健壯性考慮的場景必然很多,二進制則不同,只認0和1的組合.基于這種考慮,HTTP/2.0 的協議決定采用二進制格式,實現方便且健壯
- 多路復用(MultiPlexing),即連接共享,即每一個request都是用作連接共享機制.一個request對應一個id,這樣一個連接上可以有多個request,每個連接的request可以隨機的混雜在一起,接收方可以根據request的id將request再歸屬到各自不同的服務端請求里面
- header壓縮,如上文中所言,對前面提到過HTTP/1.x的header帶有大量信息,而且每次都要重復發送,HTTP2.0使用encoder來減少需要傳輸的header大小,通訊雙方各自cache一份header fields表,既避免header的傳輸,又減少了需要傳輸的大小.
- 服務端推送(server push),同SPDY一樣,HTTP/2.0也具有server push功能.
6. 狀態碼: 400、401和403
(1) 400(Bad Request): 告訴客戶端,它發送了一條異常請求
(2) 401(unauthorized): 表示發送的請求需要有通過HTTP認證的認證信息
(3) 403(forbidden): 表示對請求資源的訪問被服務器拒絕
7. 跨域資源共享CORS詳解
- 跨域資源共享 CORS 詳解 - 阮一峰
CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-Origin resource sharing)
它允許瀏覽器向跨源服務器發出XMLHttpRequest請求,從而客服AJAX只能同源使用的限制
7.1 簡介
- CORS需要瀏覽器和服務端同時支持(目前,所有瀏覽器都支持該功能)
- 整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與.對于開發者來說,CORS通信與同源的AJAX通信幾乎沒有差別,代碼完全一樣.瀏覽器一旦發現AJAX請求跨域,就會自動添加一些附加的頭信息,有時會多出一次附加請求,但用戶不會有感覺
- 因此,實現CORS通信的關鍵是服務器端.只要服務器端實現了CORS接口,就可以跨院通信
7.2 兩種請求
瀏覽器將CORS請求分為兩類: 簡單請求(simple request) 和 非簡單請求(not-so-simple request),只要同時滿足以下兩大條件,就屬于簡單請求:
(1) 請求方法是以下三種方法之一:- HEAD- GET- POST
(2) HTTP的頭信息不超過以下幾種字段:- Accept- Accept-Language- Content-Language- Last-Event-ID
7.3 簡單請求
- 基本流程
-
對于簡單請求,瀏覽器直接發出CORS請求.具體來說,就是在頭信息之中,增加一個Origin字段.
-
下面是一個小栗子: 瀏覽器發現這次跨源AJAX請求是簡單請求,就自動在頭信息中,添加一個Origin字段.
GET /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
- 上面頭信息中,Origin字段用來說明,本次請求來自哪個源(協議 + 域名 + 端口).服務器根據這個值,決定是否同意這次請求
- 如果Origin指定的源,不在許可范圍內,服務器會返回一個正常的HTTP響應.瀏覽器發現,這個回應的頭信息沒有包含
Access-Control-Allow-Origin
字段(詳見下文),就知道錯了,從而拋出一個錯誤,被XMLHttpRequest的onerror回調函數捕獲。注意,這種錯誤無法通過狀態碼識別,因為HTTP回應的狀態碼可能是200. - 如果Origin指定的域名在許可范圍內,服務器返回的響應,會多出幾個頭信息字段.
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
上面的頭信息之中,有三個與CORS請求相關的字段,都以Access-Control開頭
(1) Access-Control-Allow-Origin
該字段是必須的。它的值要么是請求時Origin字段的值,要么是一個*,表示接受任意域名的請求.
(2) Access-Control-Allow-Credentials
該字段可選.它的值是一個布爾值,表示是否允許發送Cookie.默認情況下,Cookie不包括在CORS請求之中。設為true,即表示服務器明確許可,Cookie可以包含在請求中,一起發送給服務器。這個值也只能設為true,如果服務器不要瀏覽器發送Cookie,刪除該字段即可
(3) Access-Control-Expose-Headers
該字段可選.CORS請求時,XMLHttpRequest對象的getResponseHeader()方法只能拿到6個基本字段: Cache-Control、Content-Language、Content-Type、Expires、Last-Modifie、Pragma
。如果想拿到其他字段,就必須在Access-Control-Expose-Headers
里面指定。上面的栗子指定,getResponse(‘FooBar’)可以返回FooBar字段。
- withCredentials屬性
上面說到,CORS默認不發送Cookie和HTTP認證信息。如果要把Cookie發到服務器,一方面要服務器同一,指定Access-Control-Allow-Credentials
字段
Access-Control-Allow-Credentials: true
另一方面,開發者必須在Ajax請求中打開withCredentials
屬性
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
否則,即時服務器同意發送Cookie,瀏覽器也不會發送。或者,服務器要求設置Cookie,瀏覽器也不會處理
但是,如果省略withCredentials
設置,有的瀏覽器還是會一起發送Cookie.這時,可以顯式關閉: withCredentials
xhr.withCredentials = false;
需要注意的是,如果發送Cookie,Access-Control-Allow-Origin
就不能設置為星號,必須指定明確的、與請求頁面一致的域名。同時,Cookie仍然遵循同源政策,只有用服務器域名設置的Cookie才會上傳,其他域名的Cookie并不會上傳,且(跨源)原網頁代碼中的document.cookie
也無法繼續讀取服務器域名下的Cookie
7.4 非簡單請求
- 預檢請求
-
非簡單請求是那種對服務器有特殊要求的請求,比如請求方法是PUT或DELETE,或者Content-Type字段的類型是
application/json
-
非簡單請求的CORS請求,會在正式通信之前,增加一次HTTP查詢請求,稱為"預檢"請求(preflight)
-
瀏覽器先詢問服務器,當前頁面所在的域名是否在服務器的許可名單之中,以及可以使用哪些HTTP動詞和頭信息字段.只有得到肯定答復,瀏覽器才會發出正式的
XMLHttpRequest
請求,否則就會報錯
var url = "http://api.alice.com/cors";
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('X-Custome-Header', 'value');
xhr.send();
- 上面代碼中,HTTP請求的方法是PUT,并且發送了一個自定義頭部信息
X-Custom-Header
- 瀏覽器發現,這是一個非簡單請求,就會自動發出一個"預檢"請求,要求服務器確認可以這樣請求.下面是這個"預檢"請求的HTTP頭信息
OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
"預檢"請求用的請求方法是OPTIONS
,表示這個請求是用來詢問的。頭信息里面,關鍵字是Ori’gin,表示請求來自哪個源.除了Origin
字段,"預檢"請求的頭部信息包括兩個特殊字段
(1)Access-Control-Request-Method
該字段是必須的,用來列出瀏覽器的CORS請求會用哪些HTTP方法,上例是PUT
(2) Access-Control-Request-Headers
該字段是一個逗號分隔的字符串,指定瀏覽器CORS請求會額外發送的頭信息字段,上例是X-Custom-Header
- 預檢請求的回應
服務器收到"預檢"請求以后,檢查了Origin、Access-Control-Request-Method
和 Access-Control-Request-Headers
字段以后, 確認允許跨源請求,就可以做出回應
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61(Unix)
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: type/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
上面的HTTP回應中,關鍵的是Access-Control-Allow
字段,表示http://api.bob.com
可以請求數據。該字段也可以設為星號,表示同意任意跨域請求。
Access-Control-Allow-Origin: *
如果瀏覽器否定了"預檢"請求,會返回一個正常的HTTP回應,但是沒有任何CORS相關的頭部信息字段。這時,瀏覽器就會認定,服務器不會同意預檢請求,因此觸發一個錯誤,被XMLHttpRequest對象的onerror回調函數捕獲.控制臺會打印如下的報錯信息.
XMLHttpRequest cannot load http://api.alice.com
Origin http://api.bob.com.is not allowed by Access-Control-Allow-Origin.
服務器回應的其他CORS相關字段如下:
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000
8. fetch發送2次請求的原因
參考回答:
fetch發送post請求的時候,總是發送2次,第一次狀態碼204,第二次才成功?
原因很簡單,因為你用fetch的post請求的時候,導致fetch第一次發送一個Options請求,詢問服務器是否支持修改的請求頭,如果服務器支持,則在第二次中發送真正的請求.
9. HTML 5 Web存儲
參考
在客戶端存儲數據
HTML5提供了兩種在客戶端存儲數據的新方法:
- localStorage - 沒有時間限制的數據存儲
- sessionStorage - 針對一個session的數據存儲
之前,這些都是由cookie完成的.但是cookie不適合大量數據的存儲,因為它們由每個對服務器的請求來傳遞,這使得cookie速度很慢而且效率也不高
在HTML5中,數據不是由每個服務器請求傳遞的,而是只有在請求時使用數據。它使在不影響網站性能的情況下存儲大量數據成為可能。
對于不同的網站,數據存儲于不同的區域,而且一個網站只能訪問其自身的數據。
HTML5使用JavaScript來存儲和訪問數據
localStorage方法
localStorage
方法存儲的數據沒有時間限制。
- 基本使用
localStorage.lastname = "Smith";
document.write(localStorage.lastname);
- 對用戶訪問頁面的次數
if(localStorage.pagecount){localStorage.pagecount = Number(localStorage.pagecount) + 1;
} else {localStorage.pagecount = 1;
}
document.write('Visit ' + localStorage.pagecount + 'itme(s).');
sessionStorage方法
sessionStorage方法針對一個session進行數據存儲.當瀏覽器關閉后,數據會被刪除
sessionStorage.lastname = 'Smith';
document.write(sessionStorage.lastname);
10. Cookie, LocalStorage 與 SessionStorage的區別
Cookie
cookie數據始終在同源的http請求中攜帶(即時不需要),即cookie在瀏覽器和服務器間來回傳遞.而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存.cookie數據還有路徑的概念,可以限制cookie只屬于某個路徑下,存儲的大小很小只有4K左右
sessionStorage 和 localStorage
僅在當前瀏覽器關閉前有效(客戶端內存中),自然也不可能持舊保持,localStorage:始終有效,窗口或瀏覽器關閉也一致保存,因此用作持久數據;cookie只在設置的cookie過期之前一直有效,即使窗口或瀏覽器關閉
localStorage和cookie在所有同源窗口中都是共享的.
11. web worker - 淺談
參考
前言
眾所周知,JavaScript是運行在單線程環境中,也就是說無法同時運行多個腳本.假設用戶點擊一個按鈕,觸發了一段用于計算的JavaScript代碼,那么在這段代碼執行完畢之前,頁面無法響應用戶的操作.但是,如果將這段代碼交給Web Wroker去運行的話,那么情況就又不一樣了: 瀏覽器會在后臺啟動一個獨立的worker線程去專門負責訪問這段代碼的運行,因此,頁面在這段JavaScript代碼運行期間依然可以響應用戶的其他操作.
Web Worker 簡介
Web Worker是HTML5標準的一部分,這一規范定義了一套API,它允許一段JavaScript程序運行在主線程之外的另一個線程中.
值得注意的是,Web Worker規范中定義了兩類工作線程:Dedicated Worker(供單個頁面使用) 和 共享線程 Shared Worker(供多個頁面共享使用).
talk is cheap, show me the code
用途
Web Worker 的意義在于可以將一些耗時的數據處理操作從主線程中剝離,使主線程更加專注頁面渲染和交互
- 懶加載
- 文本分析
- 流媒體數據處理
- canvas圖形繪制
- 圖像處理
需要注意的點
- 由同源限制
- 無法訪問DOM節點
- 運行在另一個上下文中,無法使用Window對象
- Web Worker的運行不會影響主線程,但與主線程交互時,仍然會受到主線程單線程的瓶頸制約.換言之,如果Worker線程頻繁與主線程進行交互,主線程由于需要處理交互,仍有可能使頁面發生阻塞
- 共享線程可以被多個瀏覽器上下文(Browsing context)調用,但所有這些瀏覽上下文必需同源
線程創建
- 專用線程由
Worker()
方法創建,可以接收兩個參數,第一個參數是必填的腳本的位置,第二個參數是可選的配置對象
var worker = new Worker('worker.js')
- 共享線程使用
SharedWorker()
方法創建
var sharedWorker = new SharedWorker('shared-worker.js')
數據傳遞
Worker線程和主線程通過postMessage()
方法發送消息,通過onmessage
事件接收消息
// 主線程
var worker = new Worker('worker.js')
worker.postMessage([10, 24])
worker.onmessage = function(e) {console.log(e.data)
}// Worker 線程
onmessage = function (e) {if (e.data.length > 1) {postMessage(e.data[1] - e.data[0])}
}
【問答】:
- 如何創建web worker:
var worker = new Worker('worker.js');
worker.postMessage([10, 24]);
worker.onmessage = function(e){console.log(e.data)
}
- 檢測瀏覽器對于web worker的支持性
if(window.worker){// 檢測專用線程
}
if(window.SharedWorker){// 檢測共享線程
}
12. 對HTML語義化標簽的理解
參考 - 對HTML語義化的一些理解和記錄
為什么要使用HTML語義化標簽
- 有利于搜索引擎的建立索引、抓取
- 便于不同設備的解析
- 結構更清晰,便于團隊的維護和開發
13. Doctype
Doctype作用
<!DOCTYPE>
聲明位于HTML文檔中的第一行,處于html標簽之前,用于告知瀏覽器的解析器用什么文檔標準(標準模式和混雜模式)解析這個文檔.
標準模式
標準模式的排版和JS運作模式都是以瀏覽器支持的最高標準運行
混雜模式
向后兼容,模擬老式瀏覽器,防止瀏覽器無法兼容頁面
標準模式與混雜模式的區分
-
如果HTML文檔包含形式完整的DOCTYPE,那么他一般以標準模式呈現.
-
對于HTML4.01文檔,包含嚴格DTD的DOCTYPE常常導致頁面以標準模式呈現,DOCTYPE不存在或者格式不正確會導致文檔以混雜模式呈現
14. Cookie如何防范XSS攻擊
參考
XSS的攻擊手段
- 反射型
- 發出請求時,XSS代碼出現在URL中,作為輸入提交到服務器端,服務器端解析后響應,XSS代碼隨響應內容一起傳回給瀏覽器,最后瀏覽器解析并執行XSS代碼.這個過程像一次反射,故叫反射性XSS。
- 響應路由,并關閉瀏覽器的XSS攔截
// index.art
<body><index class=""><%- xss %></index>
</body>
// 使用的是express框架
router.get('/',function(req, res, next){res.set('X-XSS-Protection', 0);res.render('index',{xss: req.query.xss})
})
- 直接觸發
// 就瀏覽器的URL地址欄中輸入
localhost:3000/?xss=<img src="null" onerror="alert(1)" />
- 引誘觸發
http://localhost:3000/?xss=<p onclick="alert('你中了xss')">面試必中的秘密...</p>
- 在頁面中嵌套iframe - 可以通過這種方式在網頁中插入各種廣告.
http://localhost:3000/?xss=<iframe src="http://www.baidu.com/t.html"></iframe>
- 存儲型
- 存儲型XSS和反射型XSS的差別僅在于,提交的代碼會存儲在服務器端(數據庫,內存,文件系統等),下次請求目標頁面時不用再提交XSS代碼
掌握XSS的防御措施
- 編碼
字符 | 十進制 | 轉義字符 |
---|---|---|
" | " ; | " ; |
& | & ; | & ; |
< | < ; | < ; |
> | > ; | > ; |
不斷開空格(non-breaking space) |   ; | &#nbsp ; |
- 過濾
- 移除用戶上傳的DOM屬性,如onerror等
- 移除用戶上傳的Style屬性、Script節點、Iframe節點等
- 校正
- 避免直接對HTML Entity解碼
- 使用DOM Parse轉換,校正不匹配的DOM標簽
httpOnly的樣式設置
// 設置cookie
response.addHeader('Set-Cookie','uid=112; Path=/; HttpOnly');// 設置多個cookie
response.addHeader('Set-Cookie','uid=112; Path=/; HttpOnly');
response.addHeader('Set-Cookie','timeout=30; Path=/test; HttpOnly');// 設置https的cookie
response.addHeader('Set-Cookie', 'uid=112; Path=/; Secure; HttpOnly');// 設置HttpOnly屬性后,通過js腳本是讀取不到cookie,可以通過以下方式讀取
Cookie cookies[] = request.getCookie();
cookie如何防范XSS攻擊
XSS(跨站腳本攻擊)是指攻擊者再返回的HTML中嵌入javascript腳本,為了減輕這些攻擊,需要再HTTP頭部配上:
set-cookie: httponly
HTTPOnly這個屬性可以防止XSS,它會禁止javascript腳本來訪問cookie
secure這個屬性告訴瀏覽器僅在請求為https的時候發送cookie