前端點滴(網絡協議/HTML/前端優化/瀏覽器)

網絡協議/HTML/前端優化/瀏覽器

IOS七層模型

在這裏插入圖片描述
從地址欄裏輸入一個URL,到這個頁面被渲染出來,中間會發生什麼?

輸入url後,首先需要找到這個url域名的服務器ip,爲了尋找這個ip,瀏覽器首先會尋找緩存,查看緩存中是否有記錄,緩存的查找記錄爲:瀏覽器緩存-》系統緩存-》路由器緩存,緩存中沒有則查找系統的hosts文件中是否有記錄,如果沒有則查詢DNS服務器,得到服務器的ip地址後,瀏覽器根據這個ip以及相應的端口號,構造一個http請求,這個請求報文會包括這次請求的信息,主要是請求方法,請求說明和請求附帶的數據,並將這個http請求封裝在一個tcp包中,這個tcp包會依次經過傳輸層,網絡層,數據鏈路層,物理層到達服務器,服務器解析這個請求來作出響應,返回相應的html給瀏覽器,因爲html是一個樹形結構,瀏覽器根據這個html來構建DOM樹,在dom樹的構建過程中如果遇到JS腳本和外部JS連接,則會停止構建DOM樹來執行和下載相應的代碼,這會造成阻塞,這就是爲什麼推薦JS代碼應該放在html代碼的後面,之後根據外部樣式,內部樣式,內聯樣式構建一個CSS對象模型樹CSSOM樹,構建完成後和DOM樹合併爲渲染樹,這裏主要做的是排除非視覺節點,比如script,meta標籤和排除display爲none的節點,之後進行佈局,佈局主要是確定各個元素的位置和尺寸,之後是渲染頁面,因爲html文件中會含有圖片,視頻,音頻等資源,在解析DOM的過程中,遇到這些都會進行並行下載,瀏覽器對每個域的並行下載數量有一定的限制,一般是4-6個,當然在這些所有的請求中我們還需要關注的就是緩存,緩存一般通過Cache-Control、Last-Modify、Expires等首部字段控制。 Cache-Control和Expires的區別在於Cache-Control使用相對時間,Expires使用的是基於服務器 端的絕對時間,因爲存在時差問題,一般採用Cache-Control,在請求這些有設置了緩存的數據時,會先 查看是否過期,如果沒有過期則直接使用本地緩存,過期則請求並在服務器校驗文件是否修改,如果上一次 響應設置了ETag值會在這次請求的時候作爲If-None-Match的值交給服務器校驗,如果一致,繼續校驗 Last-Modified,沒有設置ETag則直接驗證Last-Modified,再決定是否返回304。
過程簡單來說就是:

  1. DNS解析
  2. TCP連接
  3. 發送HTTP請求
  4. 服務器處理請求並返回HTTP報文
  5. 瀏覽器解析渲染頁面
  6. 連接結束

下面會依次講到。。。。

網絡協議

一、 HTTP與HTTPS協議

(1)http與https概述

http: 超文本傳輸協議,是互聯網上應用最爲廣泛的一種網絡協議,是一個客戶端和服務器端請求和應答的標準(TCP),用於從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議,它可以使瀏覽器更加高效,使網絡傳輸減少。
https: 是以安全爲目標的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。
https協議的主要作用是:建立一個信息安全通道,來確保數組的傳輸,確保網站的真實性。

(2)http與https區別

(1)傳輸的安全性不同。http是明文傳輸,https設置了SSL協議(加密版的http)。
(2)鏈接方式不同,端口號也不同。http端口號80,https端口號443。
(3)鏈接狀態不同。http無狀態鏈接,https由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http更加安全。
(4)工作原理不同。http是基於TCP三次握手原理,https是基於SSL+HTTP協議構建的可進行加密傳輸原理,具體如下:

http協議/TCP協議

在這裏插入圖片描述

協議流程:
客戶端發送syn數據包到服務器,並進入SYN-SENT狀態,等待服務器的確認。
服務器收到客戶端發來的syn數據包進行驗證,正確後發送syn-ack數據包到客戶端以確認請求,並進入SYN-RCVD狀態。
客戶端收到確認後檢查服務器發送過來的syn-ack數據包,併發送ack包到服務器中,服務器驗證信息如果正確則連接建立成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨後Client與Server之間可以開始傳輸數據。

擴展

(1)SYN攻擊
在三次握手過程中,Server發送SYN-ACK之後,收到Client的ACK之前的TCP連接稱爲半連接(half-open connect),此時Server處於SYN_RCVD狀態,當收到ACK後,Server轉入ESTABLISHED狀態。SYN攻擊就是Client在短時間內僞造大量不存在的IP地址,並向Server不斷地發送SYN包,Server回覆確認包,並等待Client的確認,由於源地址是不存在的,因此,Server需要不斷重發直至超時,這些僞造的SYN包將產時間佔用未連接隊列,導致正常的SYN請求因爲隊列滿而被丟棄,從而引起網絡堵塞甚至系統癱瘓。SYN攻擊時一種典型的DDOS攻擊,檢測SYN攻擊的方式非常簡單,即當Server上有大量半連接狀態且源IP地址是隨機的,則可以斷定遭到SYN攻擊了,使用如下命令可以讓之現行:#netstat -nap | grep SYN_RECV
(2)http2.0
1.提升訪問速度(可以對於,請求資源所需時間更少,訪問速度更快,相比http1.0)
2.允許多路複用:多路複用允許同時通過單一的HTTP/2連接發送多重請求-響應信息。改善了:在http1.1中,瀏覽器客戶端在同一時間,針對同一域名下的請求有一定數量限制(連接數量),超過限制會被阻塞。
3.二進制分幀:HTTP2.0會將所有的傳輸信息分割爲更小的信息或者幀,並對他們進行二進制編碼
4.首部壓縮
5.服務器端推送

TCP(四次揮手)協議

在這裏插入圖片描述
(1)第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態。
(2)第二次揮手:Server收到FIN後,發送一個ACK給Client,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號),Server進入CLOSE_WAIT狀態。
(3)第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。
(4)第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號爲收到序號+1,Server進入CLOSED狀態,完成四次揮手。
這裏很多人就會奇怪爲什麼建立鏈接是三次握手,而斷開鏈接要四次揮手?
這是因爲服務端在LISTEN狀態下,收到建立連接請求的SYN報文後,把ACK和SYN放在一個報文裏發送給客戶端(同時發送)。而關閉連接時,當收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還能接收數據,己方也未必全部數據都發送給對方了,所以己方可以立即close,也可以發送一些數據給對方後,再發送FIN報文給對方來表示同意現在關閉連接,因此,己方ACK和FIN一般都會分開發送,所以造成了多一步流程

https協議

在這裏插入圖片描述
在這裏插入圖片描述
第一步:客戶使用https的URL訪問Web服務器,要求與Web服務器建立SSL連接。
第二步:Web服務器收到客戶端請求後,會將網站的證書信息(證書中包含公鑰)傳送一份給客戶端。
第三步:客戶端的瀏覽器與Web服務器開始協商SSL連接的安全等級,也就是信息加密的等級。
第四步:客戶端的瀏覽器根據雙方同意的安全等級,建立會話密鑰,然後利用網站的公鑰將會話密鑰加密,並傳送給網站。
第五步:Web服務器利用自己的私鑰解密出會話密鑰。
第六步:Web服務器利用會話密鑰加密與客戶端之間的通信。

(3)http請求方式

1、OPTIONS
返回服務器針對特定資源所支持的HTTP請求方法,也可以利用向web服務器發送的請求來測試服務器的功能性
2、HEAD
向服務器索與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以再不必傳輸整個響應內容的情況下,就可以獲取包含在響應小消息頭中的元信息。
3、GET
向特定的資源發出訪問、查詢請求。
4、POST
向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
5、PUT
向指定資源位置上傳其最新內容
6、DELETE
請求服務器刪除Request-URL所標識的資源
7、TRACE
回顯服務器收到的請求,主要用於測試或診斷
8、CONNECT
HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器。

詳細請瀏覽:https://www.cnblogs.com/weibanggang/p/9454581.html

擴展

(1)GET與POST區別,點擊查看博文
(2)一個圖片url訪問後直接下載怎樣實現?詳情可以點擊查看

請求的返回頭裏面,用於瀏覽器解析的重要參數就是OSS的API文檔裏面的返回http頭,決定用戶下載行爲的參數。
下載的情況下:
1.x-oss-object-type : Normal
2.x-oss-request-id : 598D5ED34F29D01FE2925F41
3.x-oss-storage-class : Standard
(3)fetch發送2次請求的原因
在這裏插入圖片描述
這種情況稱爲預檢(Preflighted)的跨域請求
當HTTP請求出現以下兩種情況時,瀏覽器認爲是帶預檢(Preflighted)的跨域請求:
1). 除GET、HEAD和POST(only with application/x-www-form-urlencoded, multipart/form-data, text/plain Content-Type)以外的其他HTTP方法。
2). 請求中出現自定義HTTP頭部。
用fetch的post請求的時候,導致fetch 第一次發送了一個Options請求,詢問服務器是否支持修改的請求頭,如果服務器支持,則在第二次中發送真正的請求。詳細點擊查看

(4)http請求頭信息

協議 說明
Accept 可接受的響應內容類型(Content-Types)。
Accept-Charset 可接受的字符集
Accept-Encoding 可接受的響應內容的編碼方式。
Accept-Language 可接受的響應內容語言列表。
Accept-Datetime 可接受的按照時間來表示的響應內容版本
Authorization 用於表示HTTP協議中需要認證資源的認證信息
Cache-Control 用來指定當前的請求/回覆中的,是否使用緩存機制。
Connection 客戶端(瀏覽器)想要優先使用的連接類型
Cookie 由之前服務器通過Set-Cookie(見下文)設置的一個HTTP協議Cookie
Content-Length 以8進製表示的請求體的長度
Content-MD5 請求體的內容的二進制 MD5 散列值(數字簽名),以 Base64 編碼的結果
Content-Type 請求體的MIME類型 (用於POST和PUT請求中)
Date 發送該消息的日期和時間(以RFC 7231中定義的"HTTP日期"格式來發送)
Expect 表示客戶端要求服務器做出特定的行爲
From 發起此請求的用戶的郵件地址
Host 表示服務器的域名以及服務器所監聽的端口號。如果所請求的端口是對應的服務的標準端口(80),則端口號可以省略。
If-Match 僅當客戶端提供的實體與服務器上對應的實體相匹配時,才進行對應的操作。主要用於像 PUT 這樣的方法中,僅當從用戶上次更新某個資源後,該資源未被修改的情況下,才更新該資源。
If-Modified-Since 允許在對應的資源未被修改的情況下返回304未修改
If-None-Match 允許在對應的內容未被修改的情況下返回304未修改( 304 Not Modified ),參考 超文本傳輸協議 的實體標記
If-Range 如果該實體未被修改過,則向返回所缺少的那一個或多個部分。否則,返回整個新的實體
If-Unmodified-Since 僅當該實體自某個特定時間以來未被修改的情況下,才發送迴應。
Max-Forwards 限制該消息可被代理及網關轉發的次數。
Origin 發起一個針對跨域資源共享的請求(該請求要求服務器在響應中加入一個Access-Control-Allow-Origin的消息頭,表示訪問控制所允許的來源)。
Pragma 與具體的實現相關,這些字段可能在請求/迴應鏈中的任何時候產生。
Proxy-Authorization 用於向代理進行認證的認證信息。
Range 表示請求某個實體的一部分,字節偏移以0開始。
Referer 表示瀏覽器所訪問的前一個頁面,可以認爲是之前訪問頁面的鏈接將瀏覽器帶到了當前頁面。Referer其實是Referrer這個單詞,但RFC製作標準時給拼錯了,後來也就將錯就錯使用Referer了。
TE 瀏覽器預期接受的傳輸時的編碼方式:可使用迴應協議頭Transfer-Encoding中的值(還可以使用"trailers"表示數據傳輸時的分塊方式)用來表示瀏覽器希望在最後一個大小爲0的塊之後還接收到一些額外的字段。
User-Agent 瀏覽器的身份標識字符串
Upgrade 要求服務器升級到一個高版本協議。
Via 告訴服務器,這個請求是由哪些代理髮出的。
Warning 一個一般性的警告,表示在實體內容體中可能存在錯誤。

(5)http請求報文

後臺將http首部分爲通用首部,請求首部,響應首部,實體首部
通用首部表示一些通用信息,比如date表示報文創建時間,

請求首部就是請求報文中獨有的,如cookie,和緩存相關的如if-Modified-Since
響應首部就是響應報文中獨有的,如set-cookie,和重定向相關的location

實體首部用來描述實體部分,如allow用來描述可執行的請求方法,content-type描述主題類型,content-Encoding描述主體的編碼方式

https://www.cnblogs.com/chenguangliang/p/6708592.html

(6)http返回常見狀態碼

1 消息
▪ 100 Continue 繼續。客戶端應繼續其請求
▪ 101 Switching Protocols 切換協議。服務器根據客戶端的請求切換協議。只能切換到更高級的協議,例如,切換到HTTP的新版本協議
▪ 102 Processing
2 成功
▪ 200 OK 請求成功。一般用於GET與POST請求
▪ 201 Created 已創建。成功請求並創建了新的資源
▪ 202 Accepted 已接受。已經接受請求,但未處理完成
▪ 203 Non-Authoritative Information
▪ 204 No Content
▪ 205 Reset Content
▪ 206 Partial Content
▪ 207 Multi-Status
3 重定向
▪ 300 Multiple Choices
▪ 301 Moved Permanently 永久移動。請求的資源已被永久的移動到新URI,返回信息會包括新的URI,瀏覽器會自動定向到新URI。今後任何新的請求都應使用新的URI代替
▪ 302 Move Temporarily 臨時移動。與301類似。但資源只是臨時被移動。客戶端應繼續使用原有URI
▪ 303 See Other 查看其它地址。與301類似。使用GET和POST請求查看
▪ 304 Not Modified 未修改。所請求的資源未修改,服務器返回此狀態碼時,不會返回任何資源。客戶端通常會緩存訪問過的資源,通過提供一個頭信息指出客戶端希望只返回在指定日期之後修改的資源
▪ 305 Use Proxy
▪ 306 Switch Proxy
▪ 307 Temporary Redirect
4 請求錯誤
▪ 400 Bad Request 客戶端請求的語法錯誤,服務器無法理解
▪ 401 Unauthorized 請求要求用戶的身份認證
▪ 402 Payment Required
▪ 403 Forbidden
▪ 404 Not Found 服務器無法根據客戶端的請求找到資源(網頁)。通過此代碼,網站設計人員可設置"您所請求的資源無法找到"的個性頁面
▪ 405 Method Not Allowed
▪ 406 Not Acceptable
▪ 407 Proxy Authentication Required
▪ 408 Request Timeout
▪ 409 Conflict
▪ 410 Gone
▪ 411 Length Required
▪ 412 Precondition Failed
▪ 413 Request Entity Too Large
▪ 414 Request-URI Too Long
▪ 415 Unsupported Media Type
▪ 416 Requested Range Not Satisfiable
▪ 417 Expectation Failed
▪ 418 I’m a teapot
▪ 421 Too Many Connections
▪ 422 Unprocessable Entity
▪ 423 Locked
▪ 424 Failed Dependency
▪ 425 Too Early
▪ 426 Upgrade Required
▪ 449 Retry With
▪ 451 Unavailable For Legal Reasons
5 服務器錯誤
▪ 500 Internal Server Error 服務器內部錯誤,無法完成請求
▪ 501 Not Implemented 服務器不支持請求的功能,無法完成請求
▪ 502 Bad Gateway
▪ 503 Service Unavailable
▪ 504 Gateway Timeout
▪ 505 HTTP Version Not Supported
▪ 506 Variant Also Negotiates
▪ 507 Insufficient Storage
▪ 509 Bandwidth Limit Exceeded
▪ 510 Not Extended
▪ 600 Unparseable Response Headers

擴展

(1)400狀態碼的產生原因
前端提交數據的字段名稱和字段類型與後臺的實體沒有保持一致
前端提交到後臺的數據應該是json字符串類型,但是前端沒有將對象JSON.stringify轉化成字符串。
解決方法:對照字段的名稱,保持一致性,將obj對象通過JSON.stringify實現序列化

(2)返回碼301和302的區別
好文:https://www.simcf.cc/2045.html

二、UDP用戶數據報協議

(1)TCP和UDP的區別

特徵點 TCP UDP
是否連接 面向連接 面向非連接
傳輸可靠性 可靠 會丟包,不可靠
應用場景 傳輸數據量大 傳輸量小
速度

(1)TCP是面向連接的,udp是無連接的即發送數據前不需要先建立鏈接。
(2)TCP提供可靠的服務。也就是說,通過TCP連接傳送的數據,無差錯,不丟失,不重複,且按序到達;UDP盡最大努力交付,即不保證可靠交付。 並且因爲tcp可靠,面向連接,不會丟失數據因此適合大數據量的交換。
(3)TCP是面向字節流,UDP面向報文,並且網絡出現擁塞不會使得發送速率降低(因此會出現丟包,對實時的應用比如IP電話和視頻會議等)。
(4)TCP只能是1對1的,UDP支持1對1,1對多。
(5)TCP的首部較大爲20字節,而UDP只有8字節。
(6)TCP是面向連接的可靠性傳輸,而UDP是不可靠的。

詳細可以查看網絡協議 – UDP協議

三、HTML5 WebSocket協議

HTML5 WebSocket:長連接,客戶端與服務端可以保持長時間的通信。
詳細可以參考:
HTML5 WebSocket
html5-websocket初探

HTML

一、HTML標籤(基礎)

在這裏插入圖片描述
詳細請點擊查看w3schoolhtml參考手冊

​行內元素不可以設置寬(width)和高(height),但可以與其他行內元素位於同一行,行內元素內一般不可以包含塊級元素。行內元素的高度一般由元素內部的字體大小決定,寬度由內容的長度控制。行內元素有以下特點: ​

  • 每一個行內元素可以和別的行內元素共享一行,相鄰的行內元素會排列在同一行裏,直到一行排不下了,纔會換行。
  • 行內元素的高度、寬度、行高及頂部和底部邊距不可設置。
  • 元素的寬度就是它包含的文字或圖片的寬度,不可改變。

(1)行內元素列表

  • a 標籤可定義錨
  • abbr 表示一個縮寫形式
  • acronym 定義只取首字母縮寫
  • b 字體加粗
  • bdo 可覆蓋默認的文本方向
  • big 大號字體加粗
  • br 換行
  • cite 引用進行定義
  • code 定義計算機代碼文本
  • dfn 定義一個定義項目
  • em 定義爲強調的內容
  • i 斜體文本效果
  • img 向網頁中嵌入一幅圖像
  • input 輸入框
  • kbd 定義鍵盤文本
  • label 標籤爲 input 元素定義標註(標記)
  • q 定義短的引用
  • samp 定義樣本文本
  • select 創建單選或多選菜單
  • small 呈現小號字體效果
  • span 組合文檔中的行內元素
  • strong 加粗
  • sub 定義下標文本
  • sup 定義上標文本
  • textarea 多行的文本輸入控件
  • tt 打字機或者等寬的文本效果
  • var 定義變量

塊級元素,該元素呈現“塊”狀,所以它有自己的寬度和高度,也就是可以自定義width和height,除此之外,塊級元素比較霸道,它獨自佔據一行高度(float浮動除外),一般可以作爲其他容器使用,可容納塊級元素和行內元素。塊級元素有以下特點:

  • 每個塊級元素都是獨自佔一行。
  • 元素的高度、寬度、行高和邊距都是可以設置的。
  • 元素的寬度如果不設置的話,默認爲父元素的寬度(父元素寬度100%)。

(2)塊元素列表

  • address 聯繫方式信息。
  • article 文章內容。HTML5
  • aside 伴隨內容。 HTML5
  • audio 音頻播放。 HTML5
  • blockquote 塊引用。
  • canvas 繪製圖形。 HTML5
  • dd 定義列表中定義條目描述。
  • div 文檔分區。
  • dl 定義列表。
  • fieldset 表單元素分組。
  • figcaption 圖文信息組標題。 HTML5
  • figure 圖文信息組 (參照 figcaption)。 HTML5
  • footer 區段尾或頁尾。 HTML5
  • form 表單。
  • h1,h2,h3,h4,h5 標題級別 1-6。
  • header 區段頭或頁頭。 HTML5
  • hgroup 標題組。 HTML5
  • hr 水平分割線。
  • noscript 不支持腳本或禁用腳本時顯示的內容。
  • ol 有序列表。
  • output 表單輸出。 HTML5
  • p 行。
  • pre 預格式化文本。
  • section 一個頁面區段。 HTML5
  • table 表格。
  • tfoot 表腳註。
  • ul 無序列表。
  • video 視頻。 HTML5

行內塊元素顧名思義,該元素既有行內元素的特性也有塊元素的特性,行內塊元素有以下特點:

  • 不自動換行
  • 能夠識別寬高
  • 默認排列方式爲從左到右

(3)行內塊元素列表

  • img 定義圖片
  • input 定義輸入框

(4)元素類型轉換display,float浮動

  • display:none , 定義元素爲空脫離文檔流(不佔空間)
  • display:block ,定義元素爲塊級元素
  • display : inline ,定義元素爲行內元素
  • display:inline-block ,定義元素爲行內塊級元素。
  • float:left/right , 定義元素浮動。
擴展

(1)iframe、frame、frameset的區別
iframe默認是塊元素,其display樣式默認值是block
frame應該說即不是塊元素也不是行內元素,它雖然有display樣式,但其默認值是none
frameset不是塊元素也不是行內元素,因爲frameset不能出現在body之內,而且也沒有display樣式.
frameset標籤下只能使用frame標籤而不能是iframe標籤,iframe標籤只能使用在非frameset的頁面中,但是包含iframe的頁面可以顯示在frame中.
(2)iframe定義、優缺點
定義:iframe元素會創建包含另一個文檔的內聯框架
缺點:

  • 會阻塞主頁面的onload事件
  • 搜索引擎無法解讀這種頁面,不利於SEO
  • iframe和主頁面共享連接池,而瀏覽器對相同區域有限制所以會影響性能。

(3)Doctype作用?嚴格模式與混雜模式如何區分?它們有何意義?
Doctype聲明於文檔最前面,告訴瀏覽器以何種方式來渲染頁面,這裏有兩種模式,嚴格模式和混雜模式。
嚴格模式的排版和JS 運作模式是 以該瀏覽器支持的最高標準運行。
混雜模式,向後兼容,模擬老式瀏覽器,防止瀏覽器無法兼容頁面。

HTML5

在這裏插入圖片描述

一、HTML5新增的元素

首先html5爲了更好的實踐web語義化,增加了header,footer,nav,aside,section等語義化標籤,在表單方面,爲了增強表單,爲input增加了color,emial,data ,range等類型,在存儲方面,提供了sessionStorage,localStorage,和離線存儲,通過這些存儲方式方便數據在客戶端的存儲和獲取,在多媒體方面規定了音頻和視頻元素audio和vedio,另外還有地理定位,canvas畫布,拖放,多線程編程的web worker和websocket協議

二、HTML5語義化標籤

HTML5語義化標籤是指正確的標籤包含了正確的內容,結構良好,便於閱讀,比如nav表示導航條,類似的還有article、header、footer等等標籤。

三、HTML5 input

詳細請訪問https://www.w3school.com.cn/html5/html_5_form_attributes.asp

四、HTML5 的緩存機制

(1)Cookie、sessionStorage、localStorage的區別

在這裏插入圖片描述
都是保存在瀏覽器端、且同源的
區別在於:
1、數據有效期不同。sessionStorage:僅在當前瀏覽器窗口關閉之前有效;localStorage:始終有效,窗口或瀏覽器關閉也一直保存,因此用作持久數據;cookie:只在設置的cookie過期時間之前有效,即使窗口關閉或瀏覽器關閉
2、cookie數據始終在同源的http請求中攜帶(即使不需要),即cookie在瀏覽器和服務器間來回傳遞,而sessionStorage和localStorage不會自動把數據發送給服務器,僅在本地保存。cookie數據還有路徑(path)的概念,可以限制cookie只屬於某個路徑下
3、存儲大小限制也不同。cookie數據不能超過4K,同時因爲每次http請求都會攜帶cookie、所以cookie只適合保存很小的數據,如會話標識。sessionStorage和localStorage雖然也有存儲大小的限制,但比cookie大得多,可以達到5M或更大
4、作用域不同。sessionStorage不在不同的瀏覽器窗口中共享,即使是同一個頁面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
5、web Storage(sessionStorage,localstorage)支持事件通知機制,可以將數據更新的通知發送給監聽者
6、web Storage的api接口使用更方便
sessionStorage與localStorage的用法一致:
window.sessionStorage.clear(all);
window.sessionStorage.removeItem(key);
window.sessionStorage.setItem(key, value);
window.sessionStorage.getItem(key)
cookie用法:
$.cookie(key);
$.cookie(key,value);

(2)Cookie

HTTP是一個無狀態協議,因此Cookie的最大的作用就是存儲sessionId用來唯一標識用戶。什麼是無狀態協議,即服務器無法判斷用戶身份。Cookie實際上是一小段的文本信息(key-value格式)。客戶端向服務器發起請求,如果服務器需要記錄該用戶狀態,就使用response向客戶端瀏覽器頒發一個Cookie。客戶端瀏覽器會把Cookie保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器檢查該Cookie,以此來辨認用戶狀態。

簡單來說打個比方,我們去銀行辦理儲蓄業務,第一次給你辦了張銀行卡,裏面存放了身份證、密碼、手機等個人信息。當你下次再來這個銀行時,銀行機器能識別你的卡,從而能夠直接辦理業務。

cookie的運行機制
當用戶第一次訪問並登陸一個網站的時候,cookie的設置以及發送會經歷以下4個步驟:

客戶端發送一個請求到服務器 --》 服務器發送一個HttpResponse響應到客戶端,其中包含Set-Cookie的頭部 --》 客戶端保存cookie(sessionId),之後向服務器發送請求時,HttpRequest請求中會包含一個Cookie的頭部 --》服務器返回響應數據

細節可以查看https://www.jianshu.com/p/e3226b36c257

node+express環境下cookie-session的使用

http.js

const express = require('express');
const app = express();
const router = require('./http_dealRequest');
const cookieSession = require('cookie-session');    // 用於驗證客戶信息
app.use(cookieSession({
    name:'sessionID',       // 命名盾牌
    keys:['chenjianer']     // 設置祕鑰
}))
app.use(router);
app.use(express.static('public'));
app.engine('html',require('express-art-template'));
app.listen(8080,(err)=>{console.log('請在瀏覽器中訪問127.0.0.1:8080')});

http_dealRequest.js(配置路由跳轉)

/*
* 建立路由方法,得到路由對象, 設置各種請求路由,導出路由器
*/
const express = require('express');
const router = express.Router();
const dealData = require('./http_dealData');

router
.get('/',dealData.getall)
.get('/getone',dealData.getone)
.get('/delone',dealData.delone)
.get('/setone',dealData.setone_get)
.post('/setone',dealData.setone_post)
.get('/login',dealData.login_get)  // 導入所需要的登錄頁面
.post('/login',dealData.login_post)  // 提交表單數據,進行驗證

module.exports = router;

http_dealData.js(處理業務邏輯)

const fs = require('fs');
const url = require('url');
const sql = require('./http-sql');
const formidable = require('formidable');
const getall = (req, res) => {
    // 攔截無狀態下訪問主頁
    if (!req.session.session_data) {
        var scr = "<script>alert('請登錄後訪問');window.location.href = '/login'</script>"
        res.setHeader('content-type', 'text/html;charset=utf-8');
        return res.end(scr);
    }
    sql.select((data) => {
        res.render('./index.html', { data: data })
    })
}
const login_get = (req, res) => {
    res.render('./login.html', {})
}
const login_post = (req, res) => {
    var form = new formidable.IncomingForm();
    form.parse(req, (err, fields) => {
        res.setHeader('content-type', 'text/html;charset=utf-8');
        sql.user2((data_name, data_psw) => {
            if (fields.username == data_name && fields.psw == data_psw) {
                req.session.session_data = fields;
                var scr = "<script>alert('登錄成功');window.location.href='/'</script>";
                res.end(scr);
            }
        })
        sql.user2((data_name, data_psw) => {
            if (fields.username != data_name || fields.psw != data_psw) {
                var scr = "<script>alert('登錄失敗');window.location.href='/login'</script>";
                res.end(scr);
            }
        })
    })
}
module.exports = { getall, getone, setone_get, setone_post, delone, login_get, login_post }

http-sql.js(服務器數據處理(簡易版 增、刪、改、查))

var mysql = require('mysql');
var connection = mysql.createConnection({
// 自己連接數據庫
    host: '...',
    user: '...',
    password: '...',
    database: '...'
})
var user2 = (callback) =>{
    var sql = "select * from users3";
    connection.query(sql, function (err, data) {
        for(i in data){
            callback(data[i].username,data[i].password);
        }
    })
}
module.exports = {where,select,del,update,user2}
擴展

(1)cookie與session的區別
1、存儲位置不同
cookie的數據信息存放在客戶端瀏覽器上。
session的數據信息存放在服務器上。
2、存儲容量不同
單個cookie保存的數據<=4KB,一個站點最多保存20個Cookie。
對於session來說並沒有上限,但出於對服務器端的性能考慮,session內不要存放過多的東西,並且設置session刪除機制。
3、存儲方式不同
cookie中只能保管ASCII字符串,並需要通過編碼方式存儲爲Unicode字符或者二進制數據。
session中能夠存儲任何類型的數據,包括且不限於string,integer,list,map等。
4、隱私策略不同
cookie對客戶端是可見的,別有用心的人可以分析存放在本地的cookie並進行cookie欺騙,所以它是不安全的。
session存儲在服務器上,對客戶端是透明對,不存在敏感信息泄漏的風險。
5、有效期上不同
開發可以通過設置cookie的屬性,達到使cookie長期有效的效果。
session依賴於名爲JSESSIONID的cookie,而cookie JSESSIONID的過期時間默認爲-1,只需關閉窗口該session就會失效,因而session不能達到長期有效的效果。
6、服務器壓力不同
cookie保管在客戶端,不佔用服務器資源。對於併發用戶十分多的網站,cookie是很好的選擇。
session是保管在服務器端的,每個用戶都會產生一個session。假如併發訪問的用戶十分多,會產生十分多的session,耗費大量的內存。
7、瀏覽器支持不同
假如客戶端瀏覽器不支持cookie:
cookie是需要客戶端瀏覽器支持的,假如客戶端禁用了cookie,或者不支持cookie,則會話跟蹤會失效。關於WAP上的應用,常規的cookie就派不上用場了。
運用session需要使用URL地址重寫的方式。一切用到session程序的URL都要進行URL地址重寫,否則session會話跟蹤還會失效。
假如客戶端支持cookie:
cookie既能夠設爲本瀏覽器窗口以及子窗口內有效,也能夠設爲一切窗口內有效。
session只能在本窗口以及子窗口內有效。
8、跨域支持上不同
cookie支持跨域名訪問。
session不支持跨域名訪問。

(3)sessionStorage

作爲html5中Web Storage的一種存儲方式,localStorage和sessionStorage一樣都是用來存儲客戶端臨時信息的對象。

W3c上給的介紹是這兩者區別在於localStorage用於持久化的本地存儲,除非主動刪除數據,否則數據是永遠不會過期的。而sessionStorage存儲的數據只有在同一個會話中的頁面才能訪問並且當會話結束後數據也隨之銷燬。因此sessionStorage不是一種持久化的本地存儲,僅僅是會話級別的存儲。個人的理解是你在打開一個頁面時記錄sessionStorage,當你把頁面或者瀏覽器關閉時session中的數據即銷燬。沒了

sessionStorage的使用
index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <input type="button" value="Login" onclick="submit()" />  
        <input type="text" name="text" id="text" />  
        <input type="button" value="show" onclick="show()" />  
        <a href="33.html" target="_blank">33.html</a>
</body>
<script>
            function submit() {  
                var str = document.getElementById("text").value.trim();  
                setInfo(str);  
                document.getElementById("text").value = "";  
            }  
            //儲存數據  
            function setInfo(name) {  
                var storage = window.sessionStorage;  
                storage.setItem('name', name);  
            }  
            //顯示數據  
            function show() {  
               var storage = window.sessionStorage;  
               var str = "your name is " + storage.getItem("name");  
               document.getElementById("text").value = str;  
            }  
         </script>  
</html>

先點擊show按鈕,在文本框出現的是“your name is null”,之後只需在文本框中輸入數據再點擊login按鈕就能把數據存儲到sessionStorage。如圖
在這裏插入圖片描述
現在點擊show 文本框就顯示“your name is xiaoming”。

然後再創建一個33.html,代碼:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script>  
        var str = window.sessionStorage;  
        alert(str.getItem("name"));  
    </script>  
</head>
<body>
</body>
</html>

最後只要點擊index.html的33.html跳轉到該頁面就能發現sessionstorage內數據是共享的。

(4)localStorage

W3c上給的介紹是這兩者區別在於localStorage用於持久化的本地存儲,除非主動刪除數據,否則數據是永遠不會過期的。

localStorage的使用
用法類似於sessionStorage的使用

擴展----瀏覽器強緩存、協商緩存篇 (重點)

瀏覽器請求流程圖

在瀏覽器第一次發起請求時,本地無緩存,向web服務器發送請求,服務器起端響應請求,瀏覽器端緩存。過程如下:
在這裏插入圖片描述
瀏覽器後續再次進行請求時:
在這裏插入圖片描述
瀏覽器緩存是瀏覽器在本地磁盤對用戶最近請求過的文檔進行存儲,當訪問者再次訪問同一頁面時,瀏覽器就可以直接從本地磁盤加載文檔。
所以根據上面的特點,瀏覽器緩存有下面的優點:

  • 減少冗餘的數據傳輸
  • 減少服務器負擔
  • 加快客戶端加載網頁的速度

瀏覽器緩存是Web性能優化的重要方式

由於瀏覽器緩存加快客戶端加載網頁的速度
後臺都沒來得及打開,返回碼就看不到了,太快了, 電腦卡? >-<
算了用上面的express啓動一個服務

http.js

const express = require('express');
const app = express();
const router = require('./http_dealRequest');
const cookieSession = require('cookie-session');    // 用於驗證客戶信息
app.use(cookieSession({
    name:'sessionID',       // 命名盾牌
    keys:['chenjianer']     // 設置祕鑰
}))
app.use(router);
app.use(express.static('public'));
app.engine('html',require('express-art-template'));
app.listen(8080,(err)=>{console.log('請在瀏覽器中訪問127.0.0.1:8080')});

啓動終端輸入:node http.js

看看第一次訪問,返回碼
在這裏插入圖片描述
在這裏插入圖片描述
第二次訪問,返回碼
在這裏插入圖片描述
在這裏插入圖片描述
返回碼爲304原因:
在第一次請求服務器的時候在獲取資源之後是會先把該資源緩存在本地的,同時服務器response返回了一個響應頭ETag,ETag全稱Entity Tag,用來標識一個資源。在具體的實現中,ETag可以是資源的hash值,也可以是一個內部維護的版本號。但不管怎樣,ETag應該能反映出資源內容的變化,這是Http緩存可以正常工作的基礎。服務器數據使用上述返回的ETag來表示,只要數據這個資源不變,這個Etag就不會變。

/*************************中間過程未修改數據

客戶端第二次請求服務器的時候,利用請求頭If-None-Match來告訴服務器自己已經有個ETag爲…的資源。如果服務器上的資源沒有變化,也就是說服務器上的資源的ETag也是…的話,服務器就不會再返回該資源的內容,而是返回一個304的響應,告訴瀏覽器該資源沒有變化,緩存有效,瀏覽器將直接調用本地緩存。

強緩存與協商緩存(重點)
強緩存相關字段有expires,cache-control。如果cache-control與expires同時存在的話,cache-control的優先級高於expires。
協商緩存相關字段有Last-Modified/If-Modified-Since,Etag/If-None-Match
上圖好像沒有提到強緩存的相關字段
ctrl+F5強制刷新頁面,再次觀察後臺顯示
在這裏插入圖片描述
緩存三大策略

一、緩存存儲策略
對於 Cache-Control 頭裏的 Public、Private、no-cache、max-age 、no-store 他們都是用來指明響應內容是否可以被客戶端存儲的,其中前4個都會緩存文件數據(關於 no-cache 應理解爲“不建議使用本地緩存”,其仍然會緩存數據到本地),後者 no-store 則不會在客戶端緩存任何響應數據。另關於 no-cache 和 max-age 有點特別----稱多重緩存頭

而通過 Cache-Control:Public/Private等常規模式設置。我們可以將 Http 響應數據存儲到本地,但此時並不意味着後續瀏覽器會直接從緩存中讀取數據並使用,因爲它無法確定本地緩存的數據是否可用(可能已經失效),還必須藉助一套鑑別機制來確認纔行。這就是“緩存過期策略”。

二、緩存過期策略

客戶端用來確認存儲在本地的緩存數據是否已過期,進而決定是否要發請求到服務端獲取數據
這個策略的作用也只有一個,那就是決定客戶端是否可直接從本地緩存數據中加載數據並展示(否則就發請求到服務端獲取)

上面我們闡述了數據緩存到了本地後還需要經過判斷才能使用,那麼瀏覽器通過什麼條件來判斷呢? 答案是:Expires,Expires 指名了緩存數據有效的絕對時間(注意是絕對時間),告訴客戶端到了這個時間點(比照客戶端時間點)後本地緩存就作廢了,在這個時間點內客戶端可以認爲緩存數據有效,可直接從緩存中加載展示。

不過 Http 緩存頭設計並沒有想象的那麼規矩,像上面提到的 Cache-Control(這個頭是在Http1.1里加進來的)頭裏的 no-cache 和 max-age 就是特例,它們既包含緩存存儲策略也包含緩存過期策略,以 max-age 爲例,它實際上相當於:

Cache-Control:public/private
Expires:當前客戶端時間 + maxAge 。

而Cache-Control:no-cache === Cache-Control:max-age=0

但是要注意的是如果cache-control與expires同時存在的話,cache-control的優先級高於expires。

三、緩存對比策略

將緩存在客戶端的數據標識發往服務端,服務端通過標識來判斷客戶端 緩存數據是否仍有效,進而決定是否要重發數據。

客戶端檢測到數據過期或瀏覽器刷新後,往往會重新發起一個 http 請求到服務器,服務器此時並不急於返回數據,而是看請求頭有沒有帶標識( If-Modified-Since、If-None-Match)過來,如果判斷標識仍然有效,則返回304告訴客戶端取本地緩存數據來用即可(這裏要注意的是你必須要在首次響應時輸出相應的頭信息(Last-Modified、ETag)到服務器)服務器會優先驗證ETag。所以說上面所說的本地緩存數據即使被認爲過期,並不等於數據從此就沒用了的道理了。
所以最終說明第一次訪問服務器Cache-Control:no-cache,返回碼200。第二次訪問,返回304的原因,就是因爲Cache-Control:no-cache可緩存,且緩存失效重新發送http請求,但是又比對正確的結果,返回304

緩存策略 緩存策略值 得出結果 備註
緩存存儲策略 Cache-Control:public/private 響應的數據會被緩存到客戶端 由Cache-Control:no-cache得來
緩存過期策略 Expires:當前客戶端時間 馬上過期第二次訪問服務器會重新發送http請求 由Cache-Control:no-cache得來
緩存對比策略 ETag: W/“fa0-jPg1f/MBYYjzWNnM698oTpLVpeo” 比對成功 瀏覽器會攜帶Etag值到服務器中進行比較,如果對比相同返回狀態碼304,服務器提示瀏覽器到本地緩存中加載數據,否則返回200服務器響應數據

再來說說常規頭,比如Cache-Control :public
下面是一個請求頭

HTTP/1.1 200 OK
Cache-Control: public
Content-Type: image/png
Last-Modified: Tue, 08 Nov 2016 06:59:00 GMT
Accept-Ranges: bytes
Date: Thu, 10 Nov 2016 02:48:50 GMT
Content-Length: 3534

其中涉及緩存的因素有

Cache-Control: public
Last-Modified: Tue, 08 Nov 2016 06:59:00 GMT

但是缺少緩存過期策略的因素expires
在這裏插入圖片描述
再看看 Chrome 瀏覽器下抓包:
在這裏插入圖片描述
實測發現:多次頁面刷新,發現只發送了一次http請求,剩下的都是直接取了本地緩存,也就是說存在某種機制使得緩存沒有過期,造成客戶端不能重新發送http請求,而是直接從本地緩存中獲取數據,後又由於對比失敗返回狀態碼200,經過對比發現:
在這裏插入圖片描述
原來,在沒有提供任何瀏覽器緩存過期策略的情況下,瀏覽器遵循一個啓發式緩存過期策略:

根據響應頭中2個時間字段 Date 和 Last-Modified 之間的時間差值,取其值的10%作爲緩存時間週期配置expires。

所以,得出結論

緩存策略 緩存策略值 得出結果 備註
緩存存儲策略 Cache-Control:public 響應的數據會被緩存到客戶端 由Cache-Control:public得來
緩存過期策略 Expires:當前客戶端時間+(Date - Last-Modified)*10% 怎麼算也不可能過期 由啓發式緩存過期策略:響應頭中2個時間字段 Date 和 Last-Modified 之間的時間差值,取其值的10%作爲緩存時間週期配置expires得來
緩存對比策略 Last-Modified: Tue, 08 Nov 2016 06:59:00 GMT 比對失敗 瀏覽器會攜帶Last-Modified/Etag值到服務器中進行比較,如果對比相同返回狀態碼304,服務器提示瀏覽器到本地緩存中加載數據,否則返回200服務器響應數據

總結:
協商緩存就是將資源一些相關信息返回服務器,讓服務器判斷瀏覽器是否能直接使用本地緩存,整個過程至少與服務器通信一次

第一次訪問,狀態碼200 第二次訪問,返回碼200 第二次訪問,返回碼304
緩存存儲策略 有緩存 有緩存
緩存過期策略 緩存過期,重新發送http請求 緩存過期,重新發送http請求
緩存對比策略 對比失敗,不可用,刷新 對比成功,可用

強緩存直接使用本地的緩存,不用跟服務器進行通信

第一次訪問,狀態碼200 第二次訪問,返回碼200
緩存存儲策略 有緩存
緩存過期策略 緩存沒過期,不發送http請求,直接從本地緩存取
緩存對比策略 對比失敗,不可用,刷新

五、audio和vedio的使用

首先了解小程序開發
https://www.jianshu.com/p/df3ff0e284a6
https://blog.csdn.net/qq_43043859/article/details/90513170
由於Chrome等各類主流瀏覽器均設置了節流模式所以audio和vedio中的atuoplay失效,MicrosoftEdge、360瀏覽器支持autoplay
所以主要還是用於H5開發

六、canvas畫布的使用

推薦
https://blog.csdn.net/u012468376/article/details/73350998
https://blog.csdn.net/paulxin2008/article/details/20940255

七、drag拖動特效

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style type="text/css">
        #div1 {
            width: 198px;
            height: 66px;
            padding: 10px;
            border: 1px solid #aaaaaa;
        }
    </style>
    <script type="text/javascript">
        function allowDrop(ev) {
            ev.preventDefault();
        }
        function drag(ev) {
            ev.dataTransfer.setData("Text", ev.target.id);
        }
        function drop(ev) {
            ev.preventDefault();
            var data = ev.dataTransfer.getData("Text");
            ev.target.appendChild(document.getElementById(data));
        }
    </script>
</head>
<body>
    <p>請把 123 拖放到矩形中:</p>
    <div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
    <br />
    <p id="drag1" draggable="true" ondragstart="drag(event)" >123</p>
</body>
</html>

在這裏插入圖片描述
draggable:設置成是否允許被拖動
dragstart:事件主體是被拖放元素,在開始拖放被拖放元素時觸發,。
darg:事件主體是被拖放元素,在正在拖放被拖放元素時觸發。
dragenter:事件主體是目標元素,在被拖放元素進入某元素時觸發。
dragover:事件主體是目標元素,在被拖放在某元素內移動時觸發。
dragleave:事件主體是目標元素,在被拖放元素移出目標元素是觸發。
drop:事件主體是目標元素,在目標元素完全接受被拖放元素時觸發。
dragend:事件主體是被拖放元素,在整個拖放操作結束時觸發

八、Web Worker多線程數據的交互

在HTML頁面中,如果在執行腳本時,頁面的狀態是不可相應的,直到腳本執行完成後,頁面才變成可相應。web worker是運行在後臺的js,獨立於其他腳本,不會影響頁面你的性能。並且通過postMessage將結果回傳到主線程。這樣在進行復雜操作的時候,就不會阻塞主線程了。

如何創建web worker:

  • 檢測瀏覽器對於web worker的支持性 (Chrome瀏覽器不支持web worker)
  • 創建web worker文件(js,回傳函數等)
  • 創建web worker對象

業務如下,隨機生成一個整數數組,然後將該整數數組傳入線程,挑選出數組中可以被3整除的數字,然後顯示在頁面的表格中,主頁面代碼如下:

主線程index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Document</title>
	<script type="text/javascript" src="jquery-3.3.1.js"></script>
	<!-- 業務如下,隨機生成一個整數數組,然後將該整數數組傳入線程,挑選出數組中可以被3整除的數字,然後顯示在頁面的表格中,主頁面代碼如下: -->
	<script>
		$(function () {
			var arr = new Array(100);
			for (var i = 0; i < arr.length; i++) {
				arr[i] = parseInt(Math.random() * 100);
			};
			var worker = new Worker("myWorker.js");
			worker.postMessage(JSON.stringify(arr));
			worker.addEventListener("message", function (event) {
				if (event.data != "") {
					var array = JSON.parse(event.data);
					var row, col;
					for (var index = 0; index < array.length; index++) {
						row = parseInt(index / 10);
						col = index % 10;
						if (col == 0) {
							$("<tr>").appendTo("tbody");
						}
						$("<td>").text(array[row * 10 + col]).appendTo("tbody tr:last");
					}
				}
			}, false)
		})
	</script>
</head>
<body>
	<table>
		<caption>從隨機生成的數字中抽取3的倍數並顯示</caption>
		<tbody></tbody>
	</table>
</body>
</html>

子線程myWorker.js

self.addEventListener("message", function (event) {
    var data = JSON.parse(event.data);
    var returnArray = new Array();
    var temp;
    for (var index = 0; index < data.length; index++) {
        if ((temp = data[index]) % 3 == 0) {
            returnArray.push(temp);
        }
    }
    self.postMessage(JSON.stringify(returnArray));
}, false);

在Chrome瀏覽器下運行,不支持多線層編程
在這裏插入圖片描述
在MicrosoftEdge下運行,支持多線層編寫
在這裏插入圖片描述

一、線程嵌套

線程中可以嵌套子線程,這樣我們可以把一個較大的後臺線程切分成幾個子線程,在每個子線程中各自完成相對獨立的一部分工作。稱之爲單層嵌套

二、單層嵌套

上面的主線程可以繼續拆分成各個單層,來完成更大的工程

修改主線程index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Document</title>
	<script type="text/javascript" src="jquery-3.3.1.js"></script>
	<!-- 業務如下,隨機生成一個整數數組,然後將該整數數組傳入線程,挑選出數組中可以被3整除的數字,然後顯示在頁面的表格中,主頁面代碼如下: -->
	<script>
		$(function () {
			var worker = new Worker("myWorker.js");
			worker.postMessage("");
			worker.addEventListener("message", function (event) {
				if (event.data != "") {
					var array = JSON.parse(event.data);
					var row, col;
					for (var index = 0; index < array.length; index++) {
						row = parseInt(index / 10);
						col = index % 10;
						if (col == 0) {
							$("<tr>").appendTo("tbody");
						}
						$("<td>").text(array[row * 10 + col]).appendTo("tbody tr:last");
					}
				}
			}, false)
		})
	</script>
</head>
<body>
	<table>
		<caption>從隨機生成的數字中抽取3的倍數並顯示</caption>
		<tbody></tbody>
	</table>
</body>
</html>

二級線程myWorker.js

self.addEventListener("message", function (event) {
    var arr = new Array(100);
    for (var i = 0; i < arr.length; i++) {
        arr[i] = parseInt(Math.random() * 100);
    };
    var worker = new Worker("myWorker2.js")
    worker.postMessage(JSON.stringify(arr));
    worker.addEventListener("message", function (event1) {
        self.postMessage(event1.data);   // 返回主線程挑選結果
    }, false)
}, false);

三級線程myWorker2.js

self.addEventListener("message", function (event) {
    var data = JSON.parse(event.data);
    var returnArray = new Array();
    var temp;
    for (var index = 0; index < data.length; index++) {
        if ((temp = data[index]) % 3 == 0) {
            returnArray.push(temp);
        }
    }
    self.postMessage(JSON.stringify(returnArray)); // 將返回結果返回帶上一級層級
    self.close();  // 關閉子線程
}, false)

在MicrosoftEdge下運行,支持多線層編寫
在這裏插入圖片描述
在Chrome瀏覽器下運行,不支持多線層編程
在這裏插入圖片描述
詳細還可以參考,點擊查看

擴展

addEventListener(event, function, useCapture)

其中,event指定事件名;function指定要事件觸發時執行的函數;useCapture指定事件是否在捕獲或冒泡階段執行。

前端優化

https://blog.csdn.net/Errrl/article/details/103721482
降低請求量:合併資源,減少HTTP 請求數,minify / gzip 壓縮,webP,lazyLoad,預加載。
加快請求速度:預解析DNS,減少域名數,並行加載,CDN 分發。
緩存:HTTP 協議緩存請求,離線緩存 manifest,離線數據緩存localStorage。
渲染:JS/CSS優化,加載順序,服務端渲染,pipeline。

減少HTTP 請求數

  • 儘量減少頁面的HTTP請求,可以提高頁面載入速度。
  • 減少頁面中的元素網頁中的的圖片、form、flash等等元素都會發出HTTP請求,儘可能的減少頁面中非必要的元素,可以減少HTTP請求的次數。
  • 圖片地圖(Image Maps也就是圖像熱點,圖像地圖就是把一張圖片分成若干區域,每個區域指向不同的URL地址,這些區域也稱爲熱點。ImageMaps只適用於連續的圖標。
  • CSS Sprites(CSS精靈)圖片是增加HTTP請求的最大可能者,把全站的圖標都放在一個圖像文件中,然後用CSS的background-image和background-position屬性定位來顯示其中的一小部分。這種方法把CSS寫到HMTL文件裏,而不採用外部調用,與Div+CSS中「表現與內容分離、把CSS都立出來」相悖,缺點就是不利於SEO;當然,從整體上減少HTTP請求、提高頁面載入速度,是有利於SEO的。
  • JS文件和CSS文件只有一個。合併腳本和CSS文件,可以減少了HTTP請求。有的人喜歡把CSS分成結構清晰的幾個部分,比如base.css、header.css、mianbody.css、 footer.css這樣對頁面的維護和修改是比較方便的,但是對加快服務器響應時間就存在問題了。
  • 少用location.reload(),使用location.reload() 會刷新頁面,刷新頁面時頁面所有資源(css,js,img等)會重新請求服務器。建議location.href=“當前頁url” 代替location.reload() ,使用location.href 瀏覽器會讀取本地緩存資源。
  • 動態頁面靜態化。動態網頁實際上並不是獨立存在於服務器上的網頁文件,只有當用戶請求時服務器才返回一個完整的網頁。用戶訪問動態頁面需要與數據庫服務器進行數據交換。

防抖與節流

lazyLoad懶惰加載(節流)
前端工作中,界面和效果正在變得越來越狂拽炫酷,與此同時性能也是不得不提的問題。有些項目,頁面長,圖片多,內容豐富。像商城頁面。如果同步加載時一次性加載完畢,那肯定是要等到花都謝了,loading轉的人都崩潰~。今天分享的是Lazyload技術 是一種延遲加載技術。讓頁面加載速度快到飛起、減輕服務器壓力、節約流量、提升用戶體驗。

實現思路:
頁面較長,屏幕的可視區域有限。
不設置頁面中img標籤的src屬性值或者將其指向同一個佔位圖。
圖片的實際地址存在img標籤自定義的一個屬性中,如:“data-url”。
監聽scroll,滾動到某個位置時,動態的將url替換成實際的“data-url”。

html設置:

<head>
    <meta charset="UTF-8">
    <title>Lazyload</title>
    <style type="text/css">
        .mob-wrap li {
            list-style: none;
            width: 100%;
            height: 600px;
        }
    </style>
</head>

<body>
    <ul class="mob-wrap">
        <li>
            <img class="tamp-img" alt="loading" data-src="banner1.gif">
        </li>
        <li>
            <img class="tamp-img" alt="loading" data-src="banner1.jpg">
        </li>
        <li>
            <img class="tamp-img" alt="loading" data-src="banner2.gif">
        </li>
        <li>
            <img class="tamp-img" alt="loading" data-src="banner2.gif">
        </li>
        <li>
            <img class="tamp-img" alt="loading" data-src="banner2.gif">
        </li>
        <li>
            <img class="tamp-img" alt="loading" data-src="banner2.gif">
        </li>
        <li>
            <img class="tamp-img" alt="loading" data-src="banner2.gif">
        </li>
    </ul>
</body>

js:

//節流函數
    _throttle = (fn, delay, least) => {
        var timeout = null,
            startTime = new Date();
        fn();
        return function () {
            var curTime = new Date();
            clearTimeout(timeout);
            if (curTime - startTime >= least) {
                fn();
                startTime = curTime;
            } else {
                timeout = setTimeout(fn, delay);
            }
        }
    }
    function compare() {
        var bodyScrollHeight = document.documentElement.scrollTop;// body滾動高度
        console.log(bodyScrollHeight + "替換src方法")
        var windowHeight = window.innerHeight;// 視窗高度
        var imgs = document.getElementsByClassName('tamp-img');
        for (var i = 0; i < imgs.length; i++) {
            var imgHeight = imgs[i].offsetTop;// 圖片距離頂部高度 
            if (imgHeight < windowHeight + bodyScrollHeight - 340) {
                imgs[i].src = imgs[i].getAttribute('data-src');
                imgs[i].className = imgs[i].className.replace('tamp-img', '');
            }
        }
    }
    window.onscroll = _throttle(compare, 350, 600);

preload預加載
https://blog.csdn.net/daxianghaoshuai/article/details/80988054

preload預加載與lazyLoad懶加載區別以及配置
http://baijiahao.baidu.com/s?id=1600329086509656507&wfr=spider&for=pc

瀏覽器

瀏覽器對象(BOM對象)

(1)幾個很實用的BOM屬性對象方法

  1. window對象
    window對象不但充當全局作用域,而且表示瀏覽器窗口,最常用的屬性包括
    window.innerHeight
    window.innerWidth
    window.outerWidth
    window.outerHeight
    可以獲取瀏覽器窗口的內部、外部的寬度和高度。內部寬高是指除去菜單欄、工具欄、邊框等佔位元素後,用於顯示網頁的淨寬高,外部指的是整體瀏覽器。
  2. location對象
    表示當前頁面的URL信息。例如,一個完整的URL:
    http://www.example.com:8080/path/index.html?a=1&b=2#TOP
    最常用的屬性包括
location.protocol; // 'http'
location.host; // 'www.example.com'
location.port; // '8080'
location.pathname; // '/path/index.html'
location.search; // '?a=1&b=2'
location.hash; // 'TOP'

要加載一個新頁面,可以調用location.assign()。如果要重新加載當前頁面,調用location.reload()方法非常方便。

if (confirm('重新加載當前頁' + location.href + '?')) {
    location.reload();
} else {
    location.assign('/'); // 設置一個新的URL地址
}
  1. history對象
    最常用的屬性包括
    history.go() – 前進或後退指定的頁面數 history.go(num);
    history.back() – 後退一頁
    history.forward() – 前進一頁

history對象保存了瀏覽器的歷史記錄,JavaScript可以調用history對象的back()或forward(),相當於用戶點擊了瀏覽器的“後退”或“前進”按鈕。這個對象屬於歷史遺留對象,對於現代Web頁面來說,由於大量使用AJAX和頁面交互,簡單粗暴地調用history.back()可能會讓用戶感到非常憤怒。新手開始設計Web頁面時喜歡在登錄頁登錄成功時調用history.back(),試圖回到登錄前的頁面。這是一種錯誤的方法。任何情況,你都不應該使用history這個對象了。

  1. document對象
    表示當前頁面。由於HTML在瀏覽器中以DOM形式表示爲樹形結構,document對象就是整個DOM樹的根節點。最常用的屬性包括
    document.getElementById()
    document.getElementsByTagName()
    document.querySelector()
    document.querySelectorall()
  2. screen對象
    表示整個屏幕的信息,常用的屬性有
    screen.width:屏幕寬度,以像素爲單位;
    screen.height:屏幕高度,以像素爲單位;
    screen.colorDepth:返回顏色位數,如8、16、24。
  3. navigator對象
    表示瀏覽器的信息,最常用的屬性包括
    navigator.appName:瀏覽器名稱;
    navigator.appVersion:瀏覽器版本;
    navigator.language:瀏覽器設置的語言;
    navigator.platform:操作系統類型;
    navigator.userAgent:瀏覽器設定的User-Agent字符串。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章