1. 加載和執(zhí)行
盡量將所有的<script>標(biāo)簽放在</body>標(biāo)簽之前,確保腳本執(zhí)行前頁面已經(jīng)完成了渲染,避免腳本的下載阻塞其他資源(例如圖片)的下載。
合并腳本,減少頁面中的<script>標(biāo)簽
使用<script>標(biāo)簽的defer和async屬性(兩者的區(qū)別見這里)
通過Javascript動態(tài)創(chuàng)建<script>標(biāo)簽插入文檔來下載,其不會影響頁面其他進(jìn)程
2.數(shù)據(jù)存取
由于作用域鏈的機(jī)制,訪問局部變量比訪問跨作用域變量更快,因此在函數(shù)中若要多次訪問跨作用域變量,則可以用局部變量保存。
避免使用with語句,其會延長作用域鏈
嵌套的對象成員會導(dǎo)致引擎搜索所有對象成員,避免使用嵌套,例如window.location.href
對象的屬性和方法在原型鏈的位置越深,訪問的速度也越慢
3.Dom編程
進(jìn)行大段HTML更新時,推薦使用innerHTML,而不是DOM方法
HTML集合是一個與文檔中元素綁定的類數(shù)組對象,其長度隨著文檔中元素的增減而動態(tài)變化,因此避免在每次循環(huán)中直接讀取HTML集合的length,容易導(dǎo)致死循環(huán)
使用節(jié)點(diǎn)的children屬性,而不是childNodes屬性,前者訪問速度更快,且不包含空白文本和注釋節(jié)點(diǎn)。
瀏覽器的渲染過程包括構(gòu)建DOM樹和渲染樹,當(dāng)DOM元素的幾何屬性變化時,需要重新構(gòu)造渲染樹,這一過程稱為“重排”,完成重排后,瀏覽器會重新繪制受影響的部分到屏幕中,這一過程稱為“重繪”。因此應(yīng)該盡量合并多次對DOM的修改,或者先將元素脫離文檔流(display:none、文檔片段),應(yīng)用修改后,再插入文檔中。
每次瀏覽器的重排時都會產(chǎn)生消耗,大多數(shù)瀏覽器會通過隊(duì)列化修改并批量執(zhí)行來優(yōu)化重排過程,可當(dāng)訪問元素offsetTop、scrollTop、clientTop、getComputedStyle等一系列布局屬性時,會強(qiáng)制瀏覽器立即進(jìn)行重排返回正確的值。因此不要在dom布局信息改變時,訪問這些布局屬性。
當(dāng)修改同個元素多個Css屬性時,可以使用CssText屬性進(jìn)行一次性修改樣式,減少瀏覽器重排和重繪的次數(shù)
當(dāng)元素發(fā)生動畫時,可以使用絕對定位使其脫離文檔流,動畫結(jié)束后,再恢復(fù)定位。避免動畫過程中瀏覽器反復(fù)重排文檔流中的元素。
多使用事件委托,減少監(jiān)聽事件
4.算法和流程控制
for循環(huán)和while循環(huán)性能差不多,除了for-in循環(huán)最慢(其要遍歷原型鏈)
循環(huán)中要減少對象成員及數(shù)組項(xiàng)的查詢次數(shù),可以通過倒序循環(huán)提高性能
循環(huán)次數(shù)大于1000時,可運(yùn)用Duff Devices減少迭代次數(shù)
switch比if-else快,但如果具有很多離散值時,可使用數(shù)組或?qū)ο髞順?gòu)建查找表
遞歸可能會造成調(diào)用棧溢出,可將其改為循環(huán)迭代
如果可以,對一些函數(shù)的計算結(jié)果進(jìn)行緩存
5.字符串和正則表達(dá)式
進(jìn)行大量字符串的連接時,+和+=效率比數(shù)組的join方法要高
當(dāng)創(chuàng)建了一個正則表達(dá)式對象時,瀏覽器會驗(yàn)證你的表達(dá)式,然后將其轉(zhuǎn)化為一個原生代碼程序,用戶執(zhí)行匹配工作。當(dāng)你將其賦值給變量時,可以避免重復(fù)執(zhí)行該步驟。
當(dāng)正則進(jìn)入使用狀態(tài)時,首先要確定目標(biāo)字符串的起始搜索位置(字符串的起始位置或正則表達(dá)式的lastIndex屬性),之后正則表達(dá)式會逐個檢查文本和正則模式,當(dāng)一個特定的字元匹配失敗時,正則表達(dá)式會試著回溯到之前嘗試匹配的位置,然后嘗試其他路徑。如果正則表達(dá)式所有的可能路徑都沒有匹配到,其會將起始搜索位置下移一位,重新開始檢查。如果字符串的每個字符都經(jīng)歷過檢查,沒有匹配成功,則宣布徹底失敗。
當(dāng)正則表達(dá)式不那么具體時,例如.和[\s\S]等,很可能會出現(xiàn)回溯失控的情況,在js中可以應(yīng)用預(yù)查模擬原子組(?=(pattern))\1來避免不必要的回溯。除此之外,嵌套的量詞,例如/(A+A+)+B/在匹配"AAAAAAAA"時可能會造成驚人的回溯,應(yīng)盡量避免使用嵌套的量詞或使用預(yù)查模擬原子組消除回溯問題。
將復(fù)雜的正則表達(dá)式拆分為多個簡單的片段、正則以簡單、必需的字元開始、減少分支數(shù)量|,有助于提高匹配的效率。
setTimeout(function(){ process(todo.shift()); if (todo.length > 0) { setTimeout(arguments.callee, 25); } else { callback(); } })
setTimeout(function(){ let start = +new Date(); do { process(todo.shift()); } while(todo.length > 0 && (+new Date() - start) < 50) if (todo.length > 0) { setTimeout(arguments.callee, 25); } else { callback(); } })
WebWork
進(jìn)行計算
Expires: Mon,28 Jul 2018 23:30:30 GMT
eval
、Function
進(jìn)行雙重求值
Object
/Array
字面量定義,不要使用構(gòu)造函數(shù)
if (i & 1) { className = 'odd'; } else { className = 'even'; }
Math
對象等
簡單來說,v-if 的初始化較快,但切換代價高;v-show 初始化慢,但切換成本低
都是動態(tài)顯示DOM元素
(1)手段:
v-if是動態(tài)的向DOM樹內(nèi)添加或者刪除DOM元素;
v-show是通過設(shè)置DOM元素的display樣式屬性控制顯隱;
(2)編譯過程:
v-if切換有一個局部編譯/卸載的過程,切換過程中合適地銷毀和重建內(nèi)部的事件監(jiān)聽和子組件;
v-show只是簡單的基于css切換;
(3)編譯條件:
v-if是惰性的,如果初始條件為假,則什么也不做;只有在條件第一次變?yōu)檎鏁r才開始局部編譯(編譯被緩存?編譯被緩存后,然后再切換的時候進(jìn)行局部卸載);
v-show是在任何條件下(首次條件是否為真)都被編譯,然后被緩存,而且DOM元素保留;
(4)性能消耗:
v-if有更高的切換消耗;
v-show有更高的初始渲染消耗;
(5)使用場景:
v-if適合運(yùn)營條件不大可能改變;
v-show適合頻繁切換。
為了降低開發(fā)的復(fù)雜度,以后端為出發(fā)點(diǎn),比如:Struts、SpringMVC 等框架的使用,就是后端的 MVC 時代;
以 SpringMVC 流程為例:
優(yōu)點(diǎn):
前后端職責(zé)很清晰: 前端工作在瀏覽器端,后端工作在服務(wù)端。清晰的分工,可以讓開發(fā)并行,測 試數(shù)據(jù)的模擬不難,前端可以本地開發(fā)。后端則可以專注于業(yè)務(wù)邏輯的處理,輸出 RESTful等接 口。
前端開發(fā)的復(fù)雜度可控: 前端代碼很重,但合理的分層,讓前端代碼能各司其職。這一塊蠻有意思 的,簡單如模板特性的選擇,就有很多很多講究。并非越強(qiáng)大越好,限制什么,留下哪些自由,代 碼應(yīng)該如何組織,所有這一切設(shè)計,得花一本書的厚度去說明。
-部署相對獨(dú)立: 可以快速改進(jìn)產(chǎn)品體驗(yàn)
缺點(diǎn):
代碼不能復(fù)用。比如后端依舊需要對數(shù)據(jù)做各種校驗(yàn),校驗(yàn)邏輯無法復(fù)用瀏覽器端的代碼。如果可 以復(fù)用,那么后端的數(shù)據(jù)校驗(yàn)可以相對簡單化。
全異步,對 SEO 不利。往往還需要服務(wù)端做同步渲染的降級方案。 性能并非最佳,特別是移動互聯(lián)網(wǎng)環(huán)境下。
SPA 不能滿足所有需求,依舊存在大量多頁面應(yīng)用。URL Design 需要后端配合,前端無法完全掌控。
NodeJS 帶來的全棧時代
前端為主的 MV* 模式解決了很多很多問題,但如上所述,依舊存在不少不足之處。隨著 NodeJS 的興 起,JavaScript 開始有能力運(yùn)行在服務(wù)端。這意味著可以有一種新的研發(fā)模式:
————————————————
版權(quán)聲明:本文為CSDN博主「叁有三分之一」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/iME_cho/article/details/105654633
塊級元素(inline):
塊級元素可以包含行內(nèi)元素和其它塊級元素,且占據(jù)父元素的整個空間,可以設(shè)置 width 和 height 屬性,瀏覽器通常會在塊級元素前后另起一個新行。
常見塊級元素:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div{ width: 150px; height: 150px; background-color: cadetblue; } </style> </head> <body> <div>塊級元素1</div> <div>塊級元素2</div> </body> </html>
分析:
塊級元素的高和寬可以被修改,而且塊級元素會在一個塊級元素之后另起一行。
行級元素
行級元素(block):
一般情況下,行內(nèi)元素只能包含內(nèi)容或者其它行內(nèi)元素,寬度和長度依據(jù)內(nèi)容而定,不可以設(shè)置,可以和其它元素和平共處于一行。
常見行級元素:
a,b,strong,span,img,label,button,input,select,textarea
特點(diǎn):
和相鄰的行內(nèi)元素在一行上
高度和寬度無效,但是水平方向上的padding和margin可以設(shè)置,垂直方向上的無效
默認(rèn)的寬度就是它本身的寬度
行內(nèi)元素只能容納純文本或者是其他的行內(nèi)元素(a標(biāo)簽除外)
例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> span{ width: 150px; height: 150px; font-size: 40px; background-color: cadetblue; } </style> </head> <body> <span>行級元素1</span> <span>行級元素2</span> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> span{ width: 150px; height: 150px; font-size: 20px; background-color: cadetblue; display: inline-block; } </style> </head> <body> <span>以前我是行級元素,</span> <span>現(xiàn)在我只想做行內(nèi)塊級元素。</span> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div{ width: 150px; height: 150px; font-size: 30px; background-color: cadetblue; display: inline; } </style> </head> <body> <div>我以前是塊級元素,</div> <div>現(xiàn)在我是行級元素!</div> </body> </html>
分析:
在VSC中,修改寬高的代碼已經(jīng)出現(xiàn)了波浪線,證明他是錯誤的,所以現(xiàn)在的div
已經(jīng)變成了行級元素。
————————————————
版權(quán)聲明:本文為CSDN博主「董小宇」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/lolly1023/article/details/105715892
其實(shí)VSCode編輯器本身自帶了一個功能(Interactive Editor Playground :可以讓你快速了解VSCode的特性,并且是可以交互的),
但很可惜它的內(nèi)容是全英文的(將VSCode設(shè)置為中文也沒用哦~),
我將每一部分截圖下來,并為你說明關(guān)鍵內(nèi)容,教你學(xué)會使用 Interactive Editor Playground
還有一些顯而易見的特性,我不會再用文字?jǐn)⑹鲆槐椋ㄋ鼈兌际菨撘颇模?br />
在下文中會涉及到大量快捷鍵的介紹,如果看不懂快捷鍵請自行百度
鼠標(biāo) = 文本光標(biāo) = 光標(biāo)
本文成于2020年4月22日,隨著VSCode的版本更迭,此部分內(nèi)容可能會略有差異(小更改不影響觀看,有較大影響的更新請?jiān)谠u論區(qū)告之,我會及時更新的)
打開VSCode > Help > Interactive Playground
你將會打開 Interactive Editor Playground 頁面
VS代碼中的核心編輯器包含許多特性。此頁高亮顯示了10個特性,每個特性介紹中都提供了代碼行供你編輯
接下來的10行內(nèi)容(你可以理解為目錄,對應(yīng)10個特性)
多光標(biāo)編輯(Multi-Cursor Editing)- 選擇一塊區(qū)域,選擇所有匹配項(xiàng),添加其余光標(biāo)等
智能感應(yīng)(intelliSense)- 獲取代碼和外部模塊的代碼幫助和參數(shù)建議
行操作(Line Actions )- 快速移動行以重新排序代碼
重命名重構(gòu)(Rename Refactoring)- 快速重命名代碼庫中的符號(比如變量名、函數(shù)名)
格式化(Formatting)- 使用內(nèi)置文檔和選擇格式使代碼看起來很棒
代碼折疊(Code Folding) - 通過折疊其他代碼區(qū)域,關(guān)注代碼中最相關(guān)的部分
錯誤和警告(Errors and Warnings)- 寫代碼時請參閱錯誤和警告
片段(Snippets)- 花更少的時間輸入片段
Emmet - 只需要敲一行代碼就能生成你想要的完整HTML結(jié)構(gòu)等(極大方便前端開發(fā))
JavaScript Type Checking- 使用零配置的TypeScript對JavaScript文件執(zhí)行類型檢查。
Multi-Cursor Editing
使用多光標(biāo)編輯可以同時編輯文檔的多個部分,極大地提高了工作效率
框式選擇
鍵盤同時按下 Shift + DownArrow(下鍵)、Shift + RightArrow(右鍵)、Shift + UpArrow(上鍵)、Shift + LeftArrow(左鍵) 的任意組合可選擇文本塊
也可以用鼠標(biāo)選擇文本時按 Shift + Alt 鍵
或使用鼠標(biāo)中鍵拖動選擇(可用性很高)
添加光標(biāo)
按 Ctrl + Alt + UpArrow 在行上方添加新光標(biāo)
或按 Ctrl + Alt + DownArrow 在行下方添加新光標(biāo)
您也可以使用鼠標(biāo)和 Alt + Click 在任何地方添加光標(biāo)(可用性很高)
在所有出現(xiàn)的字符串上創(chuàng)建光標(biāo)
選擇字符串的一個實(shí)例,例如我用鼠標(biāo)選中所有background,然后按 Ctrl + Shift + L,文本中所有的background都將被選中(可用性很高)
IntelliSense
Visual Studio Code 預(yù)裝了強(qiáng)大的JavaScript和TypeScript智能感知。
在代碼示例中,將文本光標(biāo)放在錯誤下劃線的上面,會自動調(diào)用IntelliSense
這只是智能提示的冰山一角,還有懸停在函數(shù)名上可以看到參數(shù)及其注釋(如果有)等等,它會潛移默化的帶給你極大幫助
其他語言在安裝對應(yīng)插件后,會附帶對應(yīng)語言的IntelliSense
Line Actions
分別使用 Shift + Alt + DownArrow 或 Shift + Alt + UpArrow 復(fù)制光標(biāo)所在行并將其插入當(dāng)前光標(biāo)位置的上方或下方
分別使用 Alt + UpArrow 和 Alt + DownArrow 向上或向下移動選定行(可用性很高)
用 Ctrl + Shift + K 刪除整行(可用性很高)
通過按 Ctrl + / 來注釋掉光標(biāo)所在行、切換注釋(可用性很高)
Rename Refactoring
重命名符號(如函數(shù)名或變量名)
重命名操作將在項(xiàng)目中的所有文件中發(fā)生(可用性很高)
代碼如果沒有良好的編寫格式,閱讀起來是一個折磨
Formatting可以解決編寫格式問題:無論你的代碼的格式寫的有多么糟糕,它可以將代碼格式化為閱讀性良好的格式
格式化整個文檔 Shift + Alt + F (可用性很高)
格式化當(dāng)前行 Ctrl + K Ctrl + F(即先按Ctrl,再按K,最后按F)
鼠標(biāo)右鍵 > Format Document (格式化整個文檔)
將格式化操作設(shè)置為自動化(保存時自動格式化整個文檔):Ctrl + , 輸入 editor.formatOnSave
鼠標(biāo)操作,自己嘗試一下,秒懂
快捷鍵:
折疊代碼段是基于基于縮進(jìn)
錯誤和警告將在你出現(xiàn)錯誤時,高亮該代碼行
在代碼示例中可以看到許多語法錯誤(如果沒有,請你隨便修改它,讓它出現(xiàn)錯誤)
按F8鍵可以按順序在錯誤之間導(dǎo)航,并查看詳細(xì)的錯誤消息(可用性很高)
Snippets
通過使用代碼片段,可以大大加快編輯速度
在代碼編輯區(qū),你可以嘗試輸入try并從建議列表中選擇try catch,
然后按Tab鍵或者Enter,創(chuàng)建try->catch塊
你的光標(biāo)將放在文本error上,以便編輯。如果存在多個參數(shù),請按Tab鍵跳轉(zhuǎn)到該參數(shù)。
Emmet
Emmet將代碼片段的概念提升到了一個全新的層次(前端開發(fā)的大寶貝)
你可以鍵入類似Css的可動態(tài)解析表達(dá)式,并根據(jù)在abrevision中鍵入的內(nèi)容生成輸出
比如說:
然后Enter
————————————————
版權(quán)聲明:本文為CSDN博主「索兒呀」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Zhangguohao666/article/details/105676173
最近身邊的一些小伙伴,總會遇見B端設(shè)計工作,對于這種偏后臺設(shè)計的B端設(shè)計,總會有大量的表單設(shè)計需要做,結(jié)合以前自己也有過不少表單設(shè)計的工作,在這里給大家分享一下自己對于PC端表單設(shè)計的研究,聊一聊表單在PC端中的運(yùn)用。
商業(yè)離不開數(shù)據(jù),而數(shù)據(jù)總會依賴不同的表現(xiàn)形式,不管是word文檔,還是數(shù)據(jù)可視化,都是瀏覽者通過表現(xiàn)形式來對數(shù)據(jù)進(jìn)行閱讀和分析,因此表單的設(shè)計就是一種表現(xiàn)形式,我們將捋一捋如何通過表單更好的讓用戶閱讀順暢、操作方便、總而言之就是更好用啦。
無線分割:顧名思義,列表的信息之間正常情況下沒有分割線等方法來分隔,僅僅是用間距來分隔開內(nèi)容。好處是元素更少,畫面更簡潔,但是視覺可能就沒那么清晰了,使用的出場率一般。
有線分割:同樣字面意思,就是通過簡單的分割線來分割列表中的信息,讓視線左右移動的時候更加穩(wěn)定、輕松,在表單設(shè)計中使用的出場率非常高。
斑馬線:通過深淺交替的色塊,以及色塊產(chǎn)生的對比來分隔列表中的信息,深淺深淺的循環(huán)就好像斑馬線,使用時是通過色塊產(chǎn)生對比,所以也可以使用帶有適量飽和度的色塊來區(qū)分,占頁面面積比例較大,適當(dāng)用色可以使得畫面更加活潑、豐滿,斑馬線也是出場率極高的一種展現(xiàn)形式。
斑馬線+分割線:很容易理解,就是斑馬線風(fēng)格+分割線的結(jié)合,用色塊區(qū)分的同時又加了分割線,信息之間的區(qū)分對比更加強(qiáng)烈,但是畫面層級就多了一些,沒有其他的看起來簡潔,使用出場率也一般。
卡片式:跟卡片式風(fēng)格其他設(shè)計一樣,分別用懸浮的色塊來區(qū)分,間隔的地方是背景色,分隔的力度比較強(qiáng),內(nèi)容區(qū)分的很清晰,弊端是更加占畫面的位置,尤其在信息很多列的時候,會增加大量的高度,用戶需要更多時間進(jìn)行下翻的操作。使用出場率相對其他形式來說稍低。
場景:用戶需要閱讀大量的表單數(shù)據(jù),且需要頻繁的翻頁、跳轉(zhuǎn)。
如圖,左下角可以設(shè)置界面中每頁顯示信息數(shù)量的多少,用戶可以根據(jù)自己的需要自由設(shè)置,當(dāng)瀏覽的數(shù)據(jù)較多的時候,不再需要頻繁點(diǎn)擊下一頁來瀏覽信息,只需把每頁顯示的數(shù)量調(diào)高,如此便減少了大量的操作次數(shù)。
像這樣允許用戶可以自由編輯來改進(jìn)體驗(yàn)的方式還有很多,比如可以設(shè)置顯示密度,就是以一樣的方式自由調(diào)整信息與分割線的間距。除了行間距,有的可以自由設(shè)置每一列的列間距,用戶可以根據(jù)自己的習(xí)慣來設(shè)置。
場景:用戶需要瀏覽大量的數(shù)據(jù),并需要對數(shù)據(jù)反復(fù)進(jìn)行計算、分析。
在使用大量的文字列表展示數(shù)據(jù)的同時,使用數(shù)據(jù)可視化加以配合,用戶可以更好的預(yù)覽到數(shù)據(jù)的大致情況,又可以在列表表單中閱讀到詳細(xì)的數(shù)據(jù)。
場景:用戶想根據(jù)某種條件的大小排序,來先后閱讀數(shù)據(jù)。
通過點(diǎn)擊第一排小標(biāo)題行,可以選擇不同的方式調(diào)整信息的排序方式,就和電商商品排序一樣,可以選擇金額高到低或者低到高排序,也可以選擇別的方式進(jìn)行排序,從而更快找到自己所需要的內(nèi)容。
場景:從一大堆混雜的數(shù)據(jù)當(dāng)中,尋找符合條件的自己所需要的數(shù)據(jù)。
添加篩選功能,過濾掉自己不想瀏覽的內(nèi)容,通過條件篩選,更快的更的找到自己想要的內(nèi)容、縮小查找范圍、減少達(dá)到目的所花的時間。一般通過下拉按鈕的形式選擇不同的條件來進(jìn)行篩選過濾。
場景:已知列表中某信息的名稱關(guān)鍵字,想從大量混雜的列表中快速找到。
跟篩選過濾一樣,添加關(guān)鍵字搜索功能,用戶提供部分關(guān)鍵字,可通過關(guān)鍵字查詢,最快最的找到想要的那一條內(nèi)容。一般該目標(biāo)內(nèi)容是用戶已知的,有時候是針對性的。
場景:精簡設(shè)計風(fēng)格的界面,不想界面中內(nèi)容過于繁多。
如圖,鼠標(biāo)懸停在哪一行,哪一行才會顯示該列表后面的操作按鈕,好處是減少了視覺干擾,能更快的找到捕捉到操作位置,弊端是用戶不進(jìn)行交互的時候無法發(fā)現(xiàn)操作按鈕如何出現(xiàn)。
場景:想快速獲取列表中某信息的其他附屬內(nèi)容。
如圖,點(diǎn)擊某一行后,展現(xiàn)該行的一些附屬信息??梢圆挥锰D(zhuǎn)頁面而進(jìn)一步了解該行信息的詳情。
場景:在瀏覽列表的同時,需要頻繁的對列表中的信息進(jìn)行編輯。
用戶可以直接對列表信息進(jìn)行修改、編輯,省去了跳轉(zhuǎn)再編輯的麻煩步驟,更節(jié)約時間,用戶操作起來更加方便。
場景:需要充分了解列表中不同信息的詳細(xì)說明,頻繁跳轉(zhuǎn)又過于麻煩。
和可展開列表的作用類似,但是可展開列表顯示的內(nèi)容有限,快速預(yù)覽的功能可以用側(cè)彈框的方式、彈出對話窗口的方式、以及其他方式對選中的內(nèi)容直接展示詳細(xì)信息。用戶不需要跳轉(zhuǎn)至詳情頁就可以了解到大量信息,省去繁瑣的交互流程。不再需要頻繁的跳轉(zhuǎn)到詳情-返回-跳轉(zhuǎn)到另一個詳情-返回-跳轉(zhuǎn)-返回。使用快速預(yù)覽的功能就可以很好的解決這一問題。
(PS:彈出對話窗口的方式,可以同時彈出好幾項(xiàng)列表的詳情信息進(jìn)行對比,但是側(cè)彈框因?yàn)楦叨葍?yōu)勢,可以展現(xiàn)更多內(nèi)容)
場景:列表中每條內(nèi)容顯示信息參數(shù)過多,且很多不想瀏覽。
自定義列表功能是用戶可以自由設(shè)置每行信息參數(shù)的內(nèi)容,比如我不想列表中顯示金額這一項(xiàng),就可以刪除,想要的時候可以添加回來,這樣用戶可以保留自己想要的那幾項(xiàng)內(nèi)容,可以更快更方便的閱讀到自己關(guān)心的那幾項(xiàng)參數(shù),節(jié)省了用戶的有效時間。
場景:列表橫向或者縱向過多,下翻或橫拉的時候標(biāo)題頭被隱藏,不知道自己當(dāng)前瀏覽到的參數(shù)屬于哪一項(xiàng)。
交互過程中,可以把第一排重要的東西固定,列表內(nèi)容翻動的同時,第一排仍然在原位不移動而且覆蓋列表中的其他信息,很多自帶的框架都是這樣的形式,使用的出場率也是非常高,這樣用戶可以隨時查看到自己看到的內(nèi)容是屬于哪一項(xiàng)屬性,或者是屬于哪一條信息,可以是橫向固定,也可以固定豎直的第一排標(biāo)題,也可以固定最后一塊操作點(diǎn)擊區(qū)域,具體如何固定、是否固定,根據(jù)整體的需求來選擇。
通常表單都是大量的文字,大多數(shù)的文字高度都在該行高度的三分之一左右。過于緊密用戶瀏覽不順暢,過于分開顯得畫面過于松散,不同的分割方式,間距也會有所不同。
其實(shí)上面的每一條都是一個小總結(jié),每一條在大部分的列表中都可以用到,主要還是根據(jù)實(shí)際需求來運(yùn)用這幾點(diǎn),比如分割的方式根據(jù)主體風(fēng)格來搭配,不要為了設(shè)計而設(shè)計盲目運(yùn)用,畢竟設(shè)計都是以內(nèi)容為主,尤其是表單設(shè)計,本身就是更好的表達(dá)內(nèi)容。
本文發(fā)布于人人都是產(chǎn)品經(jīng)理。
ES6 允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行賦值,這被稱為解構(gòu)(Destructuring)
本質(zhì)上,這種寫法屬于“模式匹配”,只要等號兩邊的模式相同,左邊的變量就會被賦予對應(yīng)的值
如果解構(gòu)不成功,變量的值就等于undefined
解構(gòu)賦值的規(guī)則是,只要等號右邊的值不是對象或數(shù)組,就先將其轉(zhuǎn)為對象。由于undefined和null無法轉(zhuǎn)為對象,所以對它們進(jìn)行解構(gòu)賦值,都會報錯、
交換變量的值
例如:let x=1,y=2;[x,y] = [y,x]
從函數(shù)返回多個值
函數(shù)只能返回一個值,如果要返回多個值,只能將它們放在數(shù)組或?qū)ο罄锓祷亍S辛私鈽?gòu)賦值,取出這些值就非常方便
函數(shù)參數(shù)的定義
解構(gòu)賦值可以方便地將一組參數(shù)與變量名對應(yīng)起來
提取 JSON 數(shù)據(jù),很多接口數(shù)據(jù)只需要其中某部分
例如aa.axios.get(res=>{let {data:result}=res;}),則res.data.result = result了
函數(shù)參數(shù)的默認(rèn)值
指定參數(shù)的默認(rèn)值,就避免了在函數(shù)體內(nèi)部再寫var foo = config.foo || ‘default foo’;這樣的語句
遍歷 Map 結(jié)構(gòu)
Map 結(jié)構(gòu)原生支持 Iterator 接口,配合變量的解構(gòu)賦值,獲取鍵名和鍵值就非常方便
輸入模塊的指定方法
加載模塊時,往往需要指定輸入哪些方法。解構(gòu)賦值使得輸入語句非常清晰。* const { SourceMapConsumer, SourceNode } = require(“source-map”);
左右兩側(cè)數(shù)據(jù)解構(gòu)須得吻合,或者等號左邊的模式,只匹配一部分的等號右邊的數(shù)組(屬于不完全解構(gòu))
特殊情況使用…擴(kuò)展運(yùn)算符,無值是空數(shù)組
左右兩邊等式的性質(zhì)要相同,等號的右邊不是數(shù)組(或者嚴(yán)格地說,不是可遍歷的結(jié)構(gòu)),那么將會報錯,只要某種數(shù)據(jù)結(jié)構(gòu)具有 Iterator
接口,都可以采用數(shù)組形式的解構(gòu)賦值,例如Set結(jié)構(gòu)
解構(gòu)賦值允許指定默認(rèn)值,當(dāng)一個數(shù)組成員嚴(yán)格等于undefined,默認(rèn)值才會生效,否則取賦值的值;如果默認(rèn)值是一個表達(dá)式,那么這個表達(dá)式是惰性求值的,即只有在用到的時候,才會求值;默認(rèn)值可以引用解構(gòu)賦值的其他變量,但該變量必須已經(jīng)聲明
// 數(shù)組的解構(gòu)賦值 let [a,b] = [1,2]; console.log([a,b],a);//[1, 2] 1 let [aa] = [11,22]; console.log(aa)//11 let [aaa,bbb] = [111]; console.log(aaa,bbb)//111 undefined let [head, ...tail] = [1, 2, 3, 4]; console.log(head,tail)//1,[2,3,4] let [x, y, ...z] = ['a']; console.log(x,y,z)//a undefined [] // 等號右邊不是數(shù)組會報錯 // let [ab] = 121; // conosle.log(ab)//TypeError: 121 is not iterable // let [abc] = {} // conosle.log(abc)//TypeError: {} is not iterable // 默認(rèn)值賦值 let [zz = 1] = [undefined]; console.log(zz)//1 let [zzz = 1] = [null]; console.log(zzz)//null let [foo = true] = []; console.log(foo)// true let [xxx, yyy = 'b'] = ['a']; console.log(xxx,yyy)//a,b let [xxxx, yyyy = 'b'] = ['a', undefined]; console.log(xxxx,yyyy)//a,b function f() { console.log('aaa'); } let [xx = f()] = [1]; console.log(xx)//1 let [qq=ww,ww=11] = [23,44]; console.log(qq,ww)//23,44,因?yàn)閣w申明比qq晚所以是undefined;
2、對象的解構(gòu)賦值
對象的解構(gòu)賦值的內(nèi)部機(jī)制,是先找到同名屬性,然后再賦給對應(yīng)的變量。真正被賦值的是后者,而不是前者
數(shù)組是按照位置區(qū)分,對象則是按照鍵名區(qū)分的,同樣的解構(gòu)失敗則為undefine
可將已有方法對象解構(gòu)賦值
嵌套賦值,注意是變量是否被賦值是模式還是鍵值
對象的解構(gòu)賦值可以取到繼承的屬性
如果要將一個已經(jīng)聲明的變量用于解構(gòu)賦值,必須非常小心
let xx; // {xx} = {xx: 1}這樣會報錯,
解構(gòu)賦值允許等號左邊的模式之中,不放置任何變量名。因此,可以寫出非常古怪的賦值表達(dá)式
({} = [true, false]);//可執(zhí)行
由于數(shù)組本質(zhì)是特殊的對象,因此可以對數(shù)組進(jìn)行對象屬性的解構(gòu)
objFuc(){ // 對象解構(gòu)賦值 let {b,a} = {a:1} console.log(a,b)//1 undefined // 已有對象解構(gòu)賦值 let { sin, cos } = Math;//將Math對象的對數(shù)、正弦、余弦三個方法,賦值到對應(yīng)的變量上 console.log(sin);//log() { [native code] } const { log } = console; log('hello') // hello // let { foo: baz } = { foo: 'aaa', bar: 'bbb' }; console.log(baz);//aaa // 嵌套賦值 let obj = { p: [ 'Hello', { y: 'World' } ] }; let { p,p:[x, { y }] } = obj; console.log(x,y,p)//Hello World p: ['Hello',{ y: 'World' }] //繼承賦值 const obj1 = {}; const obj2 = { foo: 'bar' }; Object.setPrototypeOf(obj1, obj2);//obj1繼承obj2 const { foo } = obj1; console.log(foo) // "bar" // 默認(rèn)值 // 錯誤的寫法 let xx; // {xx} = {xx: 1};// SyntaxError: syntax error,Uncaught SyntaxError: Unexpected token '=' ({xx} = {xx: 1});//正確寫法 console.log(xx) // 古怪的,等式左邊可為空 // ({} = [true, false]); // 對象可解構(gòu)數(shù)組 let arr = [1, 2, 3]; let {0 : first, [arr.length - 1] : last} = arr; console.log(first,last)//1 3 },
strFuc(){ // str:'yan_yan' let [a,b,c,d,e,f,g] = this.str; console.log(a,b,c,d,e,f,g)//y a n _ y a n // 對數(shù)組屬性解構(gòu)賦值 let {length} = this.str; console.log(length)//7 },
4、數(shù)值和布爾值的解構(gòu)賦值
let {toString: s} = 123; console.log(s === Number.prototype.toString,s)//true ? toString() { [native code] } let {toString: ss} = true; console.log(ss === Boolean.prototype.toString,ss)// true ? toString() { [native code] } // 右側(cè)必須是數(shù)組或?qū)ο螅瑄ndefined和null無法轉(zhuǎn)為對象,所以對它們進(jìn)行解構(gòu)賦值,都會報錯 // let { prop: x } = undefined; // TypeError // let { prop: y } = null; // TypeError
5、函數(shù)參數(shù)的解構(gòu)賦值
// 函數(shù)的解構(gòu)賦值可使用默認(rèn)值,注意默認(rèn)值是指實(shí)參的默認(rèn)值而不是形參的默認(rèn)值 function move({x=1, y=1}={}) { return [x, y]; } function move1({x, y} = { x: 0, y: 0 }) { return [x, y]; } function move2({x, y=1} = { x: 0, y: 0 }) { return [x, y]; } console.log(move({x: 3, y: 8})); // [3, 8] console.log(move({x: 3})); // [3, 1] console.log(move({})); // [1, 1] console.log(move()); // [1,1] console.log(move1({x: 3, y: 8})); // [3, 8] console.log(move1({x: 3})); // [3, 1] console.log(move1({})); // [undefined, 1] console.log(move1()); // [0,0] console.log(move2({x: 3, y: 8})); // [3, 8] console.log(move2({x: 3})); // [3, 1] console.log(move2({})); // [undefined, 1] console.log(move2()); // [0,0]
6、圓括號問題 解構(gòu)賦值雖然很方便,但是解析起來并不容易。對于編譯器來說,一個式子到底是模式,還是表達(dá)式,沒有辦法從一開始就知道,必須解析到(或解析不到)等號才能知道。 由此帶來的問題是,如果模式中出現(xiàn)圓括號怎么處理。ES6 的規(guī)則是,只要有可能導(dǎo)致解構(gòu)的歧義,就不得使用圓括號。 可以使用圓括號的情況只有一種:賦值語句的非模式部分,可以使用圓括號 總結(jié): 不管是哪一類的解構(gòu)賦值,等式右邊的數(shù)據(jù)必須是對象形式(數(shù)組也是一種對象形式) ———————————————— 版權(quán)聲明:本文為CSDN博主「Yan_an_n」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。 原文鏈接:https://blog.csdn.net/weixin_44258964/article/details/105643553
目錄
HTTP協(xié)議
HTTP請求:
HTTP響應(yīng):
會話與會話狀態(tài):
Cookie
Session
Cookie和Session的區(qū)別
HTTP協(xié)議
HTTP請求:
Post /test.php HTTP/1.1 //請求行以一個方法符號開頭,以空格分開,后面跟著請求的URI和協(xié)議的版本
Host: www.test.com //請求頭
User-agent:mozilla/5.0(windows NT 6.1: rv: 15.0)
Gecko/20100101 firefox15.0
//空白行,代表請求頭結(jié)束
Username=admin&passwd=admin //請求正文
HTTP請求方法
GET 請求獲取Request-URI所標(biāo)識的資源
POST 在Request-URI所標(biāo)識的資源后附加新的數(shù)據(jù)
HEAD 請求獲取由Request-URI所標(biāo)識的資源的響應(yīng)消息報頭
PUT 請求服務(wù)器存儲一個資源,并用Request-URI作為其標(biāo)識
常用的為GET和POST;GET和POST的區(qū)別:
GET提交的內(nèi)容會直接顯示在URL中,私密性較差,可以用于顯示一些公共資源;但是GET效率會比較高。
POST不會將內(nèi)容顯示在URL中,可以用于提交一些敏感數(shù)據(jù),例如用戶名或密碼。
HTTP響應(yīng):
HTTP/1.1 200 OK //響應(yīng)行由協(xié)議版本號,響應(yīng)狀態(tài)碼和文本描述組成
Data:sun,15 nov 2018 11:02:04 GMT //響應(yīng)頭
Server:bfe/1.0.8.9
……
Connection: keep-alive
//空白行,代表響應(yīng)頭結(jié)束
<html>
</html><title>index.heml</title> //響應(yīng)正文
HTTP的狀態(tài)碼:
狀態(tài)代碼由三位數(shù)字組成,第一個數(shù)字定義了響應(yīng)的類別,且有五種可能取值。
1xx:指示信息 —— 表示請求已接收,繼續(xù)處理。
2xx:成功 —— 表示請求已被成功接收、理解、接受。
3xx:重定向 —— 要完成請求必須進(jìn)行更進(jìn)一步的操作。
4xx:客戶端錯誤 —— 請求有語法錯誤或請求無法實(shí)現(xiàn)。
5xx:服務(wù)器端錯誤 —— 服務(wù)器未能實(shí)現(xiàn)合法的請求。
常見狀態(tài)代碼、狀態(tài)描述的說明如下。
200 OK:客戶端請求成功。
400 Bad Request:客戶端請求有語法錯誤,不能被服務(wù)器所理解。
401 Unauthorized:請求未經(jīng)授權(quán),這個狀態(tài)代碼必須和 WWW-Authenticate 報頭域一起使用。
403 Forbidden:服務(wù)器收到請求,但是拒絕提供服務(wù)。
404 Not Found:請求資源不存在,舉個例子:輸入了錯誤的URL。
500 Internal Server Error:服務(wù)器發(fā)生不可預(yù)期的錯誤。
503 Server Unavailable:服務(wù)器當(dāng)前不能處理客戶端的請求,一段時間后可能恢復(fù)正常。
會話與會話狀態(tài):
Web中的會話是指一個客戶端瀏覽器與web服務(wù)器之間連續(xù)發(fā)生一系列請求和響應(yīng)過程。會話狀態(tài)是指在會話過程中產(chǎn)生的狀態(tài)信息;借助會話狀態(tài),web服務(wù)器能夠把屬于同一會話中的一系列的請求和響應(yīng)關(guān)聯(lián)起來。
Cookie
概述
Cookie是一種在客戶端保持HTTP狀態(tài)信息的技術(shù),它好比商場發(fā)放的優(yōu)惠卡。在瀏覽器訪問Web服務(wù)器的某個資源時,由Web服務(wù)器在在HTTP響應(yīng)頭中附帶傳送給瀏覽器一片數(shù)據(jù),web服務(wù)器傳送給各個客戶端瀏覽器的數(shù)據(jù)是可以各不相同的。
一旦Web瀏覽器保存了某個Cookie,那么它在以后每次訪問該Web服務(wù)器是都應(yīng)在HTTP請求頭中將這個Cookie回傳個Web服務(wù)器。Web服務(wù)器通過在HTTP響應(yīng)消息中增加Set-Cookie響應(yīng)頭字段將CooKie信息發(fā)送給瀏覽器,瀏覽器則通過在HTTP請求消息中增加Cookie請求頭字段將Cookie回傳給Web服務(wù)器。
一個Cookie只能標(biāo)識一種信息,它至少含有一個標(biāo)識該消息的名稱(NAME)和和設(shè)置值(VALUE)。一個Web瀏覽器也可以存儲多個Web站點(diǎn)提供的Cookie。瀏覽器一般只允許存放300個Cookie,每個站點(diǎn)最多存放20個Cookie,每個Cookie的大小限制為4KB。
傳送示意圖
特點(diǎn)
存儲于瀏覽器頭部/傳輸與HTTP頭部,寫時帶屬性,讀時無屬性。由三元【name,domain,path】唯一確定Cookie。
Set-Cookie2響應(yīng)頭字段
Set-Cookie2頭字段用于指定WEB服務(wù)器向客戶端傳送的Cookie內(nèi)容,但是按照Netscape規(guī)范實(shí)現(xiàn)Cookie功能的WEB服務(wù)器, 使用的是Set-Cookie頭字段,兩者的語法和作用類似。Set-Cookie2頭字段中設(shè)置的cookie內(nèi)容是具有一定格式的字符串,它必須以Cookie的名稱和設(shè)置值開頭,格式為"名稱=值”,后面可以加上0個或多個以分號(;) 和空格分隔的其它可選屬性,屬性格式一般為 "屬性名=值”。
除了“名稱=值”對必須位于最前面外,其他的可選屬性可以任意。Cookie的名稱只能由普通的英文ASCII字符組成,瀏覽器不用關(guān)心和理解Cookie的值部分的意義和格式,只要WEB服務(wù)器能理解值部分的意義就行。大多數(shù)現(xiàn)有的WEB服務(wù)器都是采用某種編碼方式將值部分的內(nèi)容編碼成可打印的ASCII字符,RFC 2965規(guī)范中沒有明確限定編碼方式。
舉例: Set-Cookie2: user-hello; Version=1; Path=/
Cookie請求頭字段
Cookie請求頭字段中的每個Cookie之間用逗號(,)或分號(;)分隔。在Cookie請求字段中除了必須有“名稱=值”的設(shè)置外,還可以有Version、path、domain、port等屬性;在Version、path、domain、port等屬性名之前,都要增加一個“$”字符作為前綴。Version屬性只能出現(xiàn)一次,且要位于Cookie請求頭字段設(shè)置值的最前面,如果需要設(shè)置某個Cookie信息的Path、Domain、Port等屬性,它們必須位于該Cookie信息的“名稱=值”設(shè)置之后。
瀏覽器使用Cookie請求頭字段將Cookie信息會送給Web服務(wù)器;多個Cookie信息通過一個Cookie請求頭字段會送給Web服務(wù)器。
瀏覽器會根據(jù)下面幾個規(guī)則決定是否發(fā)送某個Cookie信息:
1、請求主機(jī)名是否與某個存儲的Cookie的Domain屬性匹配
2、請求的端口號是否在該Cookie的Port屬性列表中
3、請求的資源路徑是否在該Cookie的Path屬性指定的目錄及子目錄中
4、該Cookie的有效期是否已過
Path屬性的指向子目錄的Cookie排在Path屬性指向父目錄的Cookie之前
舉例: Cookie: $Version=1; Course=Java; $Path=/hello/lesson;Course=vc; $Path=/hello
Cookie的安全屬性
secure屬性
當(dāng)設(shè)置為true時,表示創(chuàng)建的Cookie會被以安全的形式向服務(wù)器傳輸,也就是只能在HTTPS連接中被瀏覽器傳遞到服務(wù)器端進(jìn)行會話驗(yàn)證,如果是HTTP連接則不會傳遞該信息,所以不會被竊取到Cookie的具體內(nèi)容。
HttpOnly屬性
如果在Cookie中設(shè)置了"HttpOnly"屬性,那么通過程序(JS腳本、Applet等)將無法讀取到Cookie信息,這樣能有效的防止XSS攻擊。
總結(jié):secure屬性 是防止信息在傳遞的過程中被監(jiān)聽捕獲后信息泄漏,HttpOnly屬性的目的是防止程序獲取cookie后進(jìn)行攻擊這兩個屬性并不能解決cookie在本機(jī)出現(xiàn)的信息泄漏的問題(FireFox的插件FireBug能直接看到cookie的相關(guān)信息)。
Session
使用Cookie和附加URL參數(shù)都可以將上一-次請求的狀態(tài)信息傳遞到下一次請求中,但是如果傳遞的狀態(tài)信息較多,將極大降低網(wǎng)絡(luò)傳輸效率和增大服務(wù)器端程序處理的難度。
概述
Session技術(shù)是一種將會話狀態(tài)保存在服務(wù)器端的技術(shù),它可以比喻成是醫(yī)院發(fā)放給病人的病歷卡和醫(yī)院為每個病人保留的病歷檔案的結(jié)合方式??蛻舳诵枰邮?、記憶和回送Session的會話標(biāo)識號,Session可以且通常是借助Cookie來傳遞會話標(biāo)識號。
Session的跟蹤機(jī)制
HttpSession對象是保持會話狀態(tài)信息的存儲結(jié)構(gòu),一個客戶端在WEB服務(wù)器端對應(yīng)一個各自的HttpSession對象。WEB服務(wù)器并不會在客戶端開始訪問它時就創(chuàng)建HttpSession對象,只有客戶端訪問某個能與客戶端開啟會話的服務(wù)端程序時,WEB應(yīng)用程序才會創(chuàng)建一個與該客戶端對應(yīng)的HttpSession對象。WEB服務(wù)器為HttpSession對象分配一個獨(dú)一無的會話標(biāo)識號, 然后在響應(yīng)消息中將這個會話標(biāo)識號傳遞給客戶端??蛻舳诵枰涀挊?biāo)識號,并在后續(xù)的每次訪問請求中都把這個會話標(biāo)識號傳送給WEB服務(wù)器,WEB服務(wù)器端程序依據(jù)回傳的會話標(biāo)識號就知道這次請求是哪個客戶端發(fā)出的,從而選擇與之對應(yīng)的HttpSession對象。
WEB應(yīng)用程序創(chuàng)建了與某個客戶端對應(yīng)的HttpSession對象后,只要沒有超出一個限定的空閑時間段,HttpSession對象就駐留在WEB服務(wù)器內(nèi)存之中,該客戶端此后訪問任意的Servlet程序時,它們都使用與客戶端對應(yīng)的那個已存在的HttpSession對象。
Session是實(shí)現(xiàn)網(wǎng)上商城的購物車的最佳方案,存儲在某個客戶Session中的一個集合對象就可充當(dāng)該客戶的一個購物車。
超時管理
WEB服務(wù)器無法判斷當(dāng)前的客戶端瀏覽器是否還會繼續(xù)訪問,也無法檢測客戶端瀏覽器是否關(guān)閉,所以,即使客戶已經(jīng)離開或關(guān)閉了瀏覽器,WEB服務(wù)器還要保留與之對應(yīng)的HttpSession對象。隨著時間的推移而不斷增加新的訪問客戶端,WEB服務(wù)器內(nèi)存中將會因此積累起大量的不再被使用的HttpSession對象,并將最終導(dǎo)致服務(wù)器內(nèi)存耗盡。WEB服務(wù)器采用“超時限制”的辦法來判斷客戶端是否還在繼續(xù)訪問如果某個客戶端在一定的時間之 內(nèi)沒有發(fā)出后續(xù)請求,WEB服務(wù)器則認(rèn)為客戶端已經(jīng)停止了活動,結(jié)束與該客戶端的會話并將與之對應(yīng)的HttpSession對象變成垃圾。
如果客戶端瀏覽器超時后再次發(fā)出訪問請求,Web服務(wù)器則認(rèn)為這是一個新的會話開始,將為之創(chuàng)建新的Httpsession對象和分配新的會話標(biāo)識號。
利用Cookie實(shí)現(xiàn)Session的跟蹤
如果WEB服務(wù)器處理某個訪問請求時創(chuàng)建了新的HttpSession對象,它將把會話標(biāo)識號作為一個Cookie項(xiàng)加入到響應(yīng)消息中,通常情況下,瀏覽器在隨后發(fā)出的訪問請求中又將會話標(biāo)識號以Cookie的形式回傳給WEB服務(wù)器。WEB服務(wù)器端程序依據(jù)回傳的會話標(biāo)識號就知道以前已經(jīng)為該客戶端創(chuàng)建了HttpSession對象,不必再為該客戶端創(chuàng)建新的HttpSession對象,而是直接使用與該會話標(biāo)識號匹配的HttpSession對象,通過這種方式就實(shí)現(xiàn)了對同一個客戶端的會話狀態(tài)的跟蹤。
利用URL重寫實(shí)現(xiàn)Session跟蹤
Servlet規(guī)范中引入了一種補(bǔ)充的會話管理機(jī)制,它允許不支持Cookie的瀏覽器也可以與WEB服務(wù)器保持連續(xù)的會話。這種補(bǔ)充機(jī)制要求在響應(yīng)消息的實(shí)體內(nèi)容中必須包含下一 次請求的超鏈接,并將會話標(biāo)識號作為超鏈接的URL地址的一個特殊參數(shù)。將會話標(biāo)識號以參數(shù)形式附加在超鏈接的URL地址后面的技術(shù)稱為URL重寫。 如果在瀏覽器不支持Cookie或者關(guān)閉了Cookie功能的情況下,WEB服務(wù)器還要能夠與瀏覽器實(shí)現(xiàn)有狀態(tài)的會話,就必須對所有能被客戶端訪問的請求路徑(包括超鏈接、form表單的action屬性設(shè)置和重定向的URL)進(jìn)行URL重寫。
Cookie和Session的區(qū)別
session和cookies同樣都是針對單獨(dú)用戶的變量(或者說是對象好像更合適點(diǎn)),不同的用戶在訪問網(wǎng)站的時候都會擁有各自的session或者cookies,不同用戶之間互不干擾。
他們的不同點(diǎn)是:
1,存儲位置不同
session在服務(wù)器端存儲,比較安全,但是如果session較多則會影響性能
cookies在客戶端存儲,存在較大的安全隱患
2,生命周期不同
session生命周期在指定的時間(如20分鐘) 到了之后會結(jié)束,不到指定的時間,也會隨著瀏覽器進(jìn)程的結(jié)束而結(jié)束。
cookies默認(rèn)情況下也隨著瀏覽器進(jìn)程結(jié)束而結(jié)束,但如果手動指定時間,則不受瀏覽器進(jìn)程結(jié)束的影響。
總結(jié):簡而言之,兩者都是保存了用戶操作的歷史信息,但是存在的地方不同;而且session和cookie的目的相同,都是為了克服HTTP協(xié)議無狀態(tài)的缺陷,但是完成方法不同。Session通過cookie在客戶端保存session id,將用戶的其他會話消息保存在服務(wù)端的session對象中;而cookie需要將所有信息都保存在客戶端,因此存在著一定的安全隱患,例如本地Cookie中可能保存著用戶名和密碼,容易泄露。
————————————————
版權(quán)聲明:本文為CSDN博主「悲觀的樂觀主義者」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_43997530/article/details/105650267
his是一個關(guān)鍵字,表示執(zhí)行當(dāng)前函數(shù)的對象
function fn(){
console.log(this); //window
console.log(typeof this); //object
}
fn();
- 嚴(yán)格模式下,this指向undefiend
"use strict";
function fn(){
console.log(this); //undefined
}
fn();
藍(lán)藍(lán)設(shè)計的小編 http://www.miumiuwan.com