整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          HTML+CSS+JS,20行代碼的貪吃蛇

          csdn上看到一位大神用20行代碼就寫(xiě)出了一個(gè)貪吃蛇的小游戲,鏈接請(qǐng)點(diǎn)這里,感覺(jué)被驚艷到了,就試著讀了一下這段代碼,閱讀過(guò)程中不斷為作者寫(xiě)法的巧妙而叫絕,其中我發(fā)現(xiàn)自己對(duì)運(yùn)算符優(yōu)先級(jí)和一些js的技巧不是很清楚,所以看完之后決定把思路分享出來(lái),方便和我一樣的小白學(xué)習(xí)。

          ??我對(duì)代碼稍稍做了些修改,并添加了一些注釋,方便理解。

          <!DOCTYPE html>
          <html lang="en">
          <head>
             <meta charset="UTF-8">
             <title>貪吃蛇重構(gòu)</title>
             <style>
                 body {
                     display: flex;
                     height: 100vh;
                     margin: 0;
                     padding: 0;
                     justify-content: center;
                     align-items: center;
                 }
             </style>
          </head>
          <body>
             <canvas id="can" width="400" height="400" style="background-color: black">對(duì)不起,您的瀏覽器不支持canvas</canvas>
             <script>
                 var snake = [41, 40],       //snake隊(duì)列表示蛇身,初始節(jié)點(diǎn)存在但不顯示
                     direction = 1,          //1表示向右,-1表示向左,20表示向下,-20表示向上
                     food = 43,              //食物的位置
                     n,                      //與下次移動(dòng)的位置有關(guān)
                     box = document.getElementById('can').getContext('2d');
                                             //從0到399表示box里[0~19]*[0~19]的所有節(jié)點(diǎn),每20px一個(gè)節(jié)點(diǎn)
          
                 function draw(seat, color) {
                     box.fillStyle = color;
                     box.fillRect(seat % 20 *20 + 1, ~~(seat / 20) * 20 + 1, 18, 18);
                                             //用color填充一個(gè)矩形,以前兩個(gè)參數(shù)為x,y坐標(biāo),后兩個(gè)參數(shù)為寬和高。
                 }
          
                 document.onkeydown = function(evt) {    
                                             //當(dāng)鍵盤上下左右鍵摁下的時(shí)候改變direction
                     direction = snake[1] - snake[0] == (n = [-1, -20, 1, 20][(evt || event).keyCode - 37] || direction) ? direction : n;
                 };
          
                 !function() {
                     snake.unshift(n = snake[0] + direction);    
                                             //此時(shí)的n為下次蛇頭出現(xiàn)的位置,n進(jìn)入隊(duì)列
                     if(snake.indexOf(n, 1) > 0 || n < 0 || n > 399 || direction == 1 && n % 20 == 0 || direction == -1 && n % 20 == 19) {
                                             //if語(yǔ)句判斷貪吃蛇是否撞到自己或者墻壁,碰到時(shí)返回,結(jié)束程序
                         return alert("GAME OVER!");
                     }
                     draw(n, "lime");        //畫(huà)出蛇頭下次出現(xiàn)的位置
                     if(n == food) {         //如果吃到食物時(shí),產(chǎn)生一個(gè)蛇身以外的隨機(jī)的點(diǎn),不會(huì)去掉蛇尾
                         while (snake.indexOf(food = ~~(Math.random() * 400)) > 0);
                         draw(food, "yellow");
                     } else {                //沒(méi)有吃到食物時(shí)正常移動(dòng),蛇尾出隊(duì)列
                         draw(snake.pop(),"black");
                     }
                     setTimeout(arguments.callee, 150);      
                                             //每隔0.15秒執(zhí)行函數(shù)一次,可以調(diào)節(jié)蛇的速度
                 }();
             </script>
          </body>
          </html>

          ??首先,我們要知道做一個(gè)貪吃蛇最主要的是什么,是做出蛇活動(dòng)的場(chǎng)所和如何使蛇動(dòng)起來(lái)。??我們先看蛇活動(dòng)的場(chǎng)所:

          <!-- html -->
             <canvas id="can" width="400" height="400" style="background-color: black">
                 對(duì)不起,您的瀏覽器不支持canvas
             </canvas>
             <!-- js -->
             box = document.getElementById('can').getContext('2d');

          ??這是一個(gè) 400px*400px的 canvas,思路是以 20px*20px為一個(gè)方格,組成 20行 20列的方陣,總共 400格,然后綠色填充的格子表示蛇身,用黃色表示食物。這 400個(gè)格子和數(shù)字 0~399一一對(duì)應(yīng),對(duì)應(yīng)的方式就是以 20作為基數(shù), n/20再取整表示第幾行, n%20表示第幾列。行數(shù)和列數(shù)都用 0~19表示。??蛇用一個(gè)一維數(shù)組表示,每個(gè)值都是這 400個(gè)數(shù)中的一個(gè),用 varsnake=[41,40];初始化這條蛇,索引 0為蛇頭。food表示食物的位置, direction表示蛇頭下一次運(yùn)動(dòng)的轉(zhuǎn)向。蛇的運(yùn)動(dòng)就用添加和刪除數(shù)組元素來(lái)實(shí)現(xiàn),每次執(zhí)行繪制蛇頭,去掉蛇尾,循環(huán)執(zhí)行使蛇運(yùn)動(dòng)。??下邊從函數(shù)運(yùn)行的起始處( 39行)開(kāi)始看:

          !function() {}();

          ??什么鬼?這其實(shí)是立即執(zhí)行函數(shù) IIFE的另一種寫(xiě)法。關(guān)于 IIFE,這篇文章講的挺不錯(cuò)的。繼續(xù)往下看,給蛇頭添加一個(gè)節(jié)點(diǎn) n,其值為當(dāng)前蛇頭的值加 direction的值,如此一來(lái)就能理解為什么要用 20表示向下, -20表示向上了。再下一行是一個(gè) if語(yǔ)句,其中值得提醒的是 &&的優(yōu)先級(jí)高于 ||,這個(gè)語(yǔ)句就是判斷即將出現(xiàn)的蛇頭是不是屬于蛇身,或者跑到box外邊去了。如果沒(méi)有死亡,就把這個(gè)蛇頭繪制出來(lái),下邊就看看繪制的代碼:

          function draw(seat, color) {
             box.fillStyle = color;
             box.fillRect(seat % 20 *20 + 1, ~~(seat / 20) * 20 + 1, 18, 18);
          }

          ??填充時(shí)填充 18*18的像素,留 1px邊框。.fillRect()中第一個(gè)參數(shù)就是要繪制的矩形的 x坐標(biāo) seat%20*20+1,即先得到所要繪制的矩形塊在方陣中的位置:第 ~~(seat/20)行,第 seat%20列,再 *20+1具體到像素點(diǎn)。可能這個(gè) ~~有點(diǎn)難理解,我感覺(jué)在這里的用處應(yīng)該和 Math.floor()差不多,對(duì)一個(gè)浮點(diǎn)型的數(shù)取反再取反,得到的數(shù)就是去掉小數(shù)位的整數(shù)了。



          ??回到 47行,又是一個(gè)判斷語(yǔ)句,判斷下次蛇頭出現(xiàn)的位置是不是和當(dāng)前的食物的位置相同,如果相同,生成下一個(gè)食物,食物的位置為一個(gè)隨機(jī)數(shù),但是要判斷這個(gè)點(diǎn)不是出現(xiàn)在當(dāng)前的蛇身上,繪制食物。如果沒(méi)有吃到食物,即蛇在正常運(yùn)動(dòng)時(shí),每向前一次,將蛇尾彈出,并利用其返回值將這個(gè)點(diǎn)重新繪制為黑色。??最后的 setTimeout,循環(huán)執(zhí)行當(dāng)前函數(shù),設(shè)置執(zhí)行周期來(lái)調(diào)蛇的移動(dòng)速度。??到了這里,我們發(fā)現(xiàn)這條蛇已經(jīng)可以動(dòng)了,加上鍵盤的操作就完成了:

          document.onkeydown = function(evt) {    
             direction = snake[1] - snake[0] == (n = [-1, -20, 1, 20][(evt || event).keyCode - 37] || direction) ? direction : n;
          };

          ??將這個(gè)函數(shù)綁定到鍵盤事件上, evt||event用法的原因這里有詳細(xì)的解釋,是為了兼容 ie。??三目運(yùn)算符 ?前邊的判斷語(yǔ)句又可分為兩部分:

          1. snake[1]-snake[0]的值應(yīng)該就是 -direction,按理說(shuō)此處寫(xiě)成 -direction應(yīng)該和原來(lái)是一個(gè)效果,那為什么沒(méi)有這么做呢,因?yàn)槿绻@樣寫(xiě),玩家可能在一個(gè)函數(shù)周期中多次改變 direction的值,最后使得 direction和當(dāng)前真正的運(yùn)動(dòng)方向不一致,導(dǎo)致游戲崩潰。
          2. 在 ==后邊, [-1,-20,1,20][(evt||event).keyCode-37]中前邊的 []是一個(gè)數(shù)組,后邊的 []是取索引,左上右下四個(gè)鍵的 keyCode分別為 37,38,39,40,計(jì)算后的索引為 0,1,2,3,使方向鍵與 direction的取值對(duì)應(yīng)起來(lái)。這里的巧妙之處在于如果按下的按鍵不是方向鍵,在數(shù)組中將得不到對(duì)應(yīng)的值,返回 undefine。此時(shí),由于之后的 ||運(yùn)算符, n會(huì)取到 direction原來(lái)的值。

          ??再用三目運(yùn)算符來(lái)判斷,如果按鍵方向不是反方向,就更新 direction的值。

          以上就是本篇的全部?jī)?nèi)容啦,雖然都是一些基礎(chǔ)的東西,但是感覺(jué)還是挺好玩的。要是哪里理解的不對(duì)還希望指證出來(lái),共同進(jìn)步。

          源自:https://segmentfault.com/a/1190000009770460

          聲明:文章著作權(quán)歸作者所有,如有侵權(quán),請(qǐng)聯(lián)系小編刪除。

          端程序員,每天接觸的都是瀏覽器。作為一個(gè)合格的前端工程師,瀏覽器相關(guān)的工作原理是我們對(duì)性能優(yōu)化的基石,今天就來(lái)考考自己對(duì)瀏覽器了解有多少?

          一、從輸入 URL 到頁(yè)面呈現(xiàn)發(fā)生了什么?

          在瀏覽器中輸入一個(gè)網(wǎng)址,如:https://www.baidu.com 。從輸入地址到我們看到百度首頁(yè),這一過(guò)程到底發(fā)生了什么?

          1.1、構(gòu)建網(wǎng)絡(luò)請(qǐng)求

          1.2、查找緩存

          檢查如果有緩存,則直接使用緩存,如果沒(méi)有緩存,則會(huì)向服務(wù)器發(fā)送網(wǎng)絡(luò)請(qǐng)求。

          1.3、DNS解析

          我們?cè)L問(wèn)網(wǎng)站的時(shí)候,輸入的是域名,比如上邊截圖內(nèi)

          域名:https://www.baidu.com

          IP地址:36.152.44.95:443

          真正的數(shù)據(jù)包是通過(guò) IP 地址傳過(guò)來(lái)的,域名和 IP 是 一 一 映射關(guān)系。我們根據(jù)域名獲取到具體的 IP 這個(gè)過(guò)程就叫做 DNS 解析。

          IP 地址后的數(shù)字指定的端口號(hào),如果沒(méi)有,默認(rèn)是 80 。

          1.4、建立 TCP 連接

          服務(wù)器要是想把數(shù)據(jù)包傳給瀏覽器之前,首先要建立連接。建立 TCP 連接,就是保證服務(wù)器與瀏覽器之間能夠進(jìn)行安全連接通信,數(shù)據(jù)傳輸完畢之后再斷開(kāi)連接。

          TCP (Transmission Control Protocol),傳輸控制協(xié)議,是一種面向連接的,可靠的,基于字節(jié)流的傳輸層通信協(xié)議。

          同一個(gè)域名下,最多能夠建立 6 個(gè) TCP 連接,超過(guò) 6 個(gè)的話,剩余的會(huì)排隊(duì)等待。TCP 連接分為三個(gè)階段:

          • 通過(guò)三次握手建立瀏覽器與服務(wù)器之間的連接。
          • 進(jìn)行數(shù)據(jù)傳輸,服務(wù)器向?yàn)g覽器發(fā)送數(shù)據(jù)包。
          • 斷開(kāi)連接的階段,數(shù)據(jù)傳輸完畢之后,通過(guò)四次揮手來(lái)斷開(kāi)連接。

          1.5、發(fā)送 HTTP 請(qǐng)求

          TCP 建立連接完畢后,瀏覽器和服務(wù)器可以開(kāi)始通信了,即開(kāi)始發(fā)送 HTTP 請(qǐng)求。

          http 請(qǐng)求,前端程序員就很熟悉嘍!有請(qǐng)求和響應(yīng)。

          網(wǎng)絡(luò)請(qǐng)求流程圖:

          二、頁(yè)面是如何渲染的?

          第一個(gè)問(wèn)題講的瀏覽內(nèi)輸入 url 之后做了做了些啥,最后到發(fā)送網(wǎng)絡(luò)請(qǐng)求。服務(wù)器根據(jù) url 提供的地址查找文件,然后加載 html、css、js、img等資源文件。接收到文件之后瀏覽器是如何渲染的呢?

          瀏覽器渲染的過(guò)程為:

          1. 瀏覽器將獲取的 html 文檔解析成 DOM 樹(shù)。
          2. 處理 CSS 標(biāo)記,構(gòu)成層疊樣式表模型CSSOM。
          3. 將 DOM 和 CSSOM 合并,創(chuàng)建渲染樹(shù)(rendering tree),代表一系列將被渲染的對(duì)象。
          4. 渲染樹(shù)的每個(gè)元素包含的內(nèi)容都是計(jì)算過(guò)的,它被稱為布局 layout 。瀏覽器使用流式布局的方式,只需一次繪制操作布局所有的元素。
          5. 將渲染樹(shù)的各個(gè)節(jié)點(diǎn)繪制到屏幕上,這一步被稱之為 painting。

          圖示:

          三、瀏覽器緩存是怎么回事?

          3.1、強(qiáng)緩存

          檢查強(qiáng)緩存的時(shí)候,不會(huì)發(fā)送 http 請(qǐng)求。

          如何來(lái)檢查呢?通過(guò)相應(yīng)的字段來(lái)進(jìn)行檢查的,在 hTTP/1.0 中使用的是 Expires /,在 HTTP/1.1 使用的是 Cache-Control 。

          Expires

          Expires 即過(guò)期時(shí)間,存在于服務(wù)端返回的響應(yīng)頭,告訴瀏覽器在過(guò)期時(shí)間之前可以直接從緩存內(nèi)獲取數(shù)據(jù),無(wú)需再次發(fā)送網(wǎng)絡(luò)請(qǐng)求。

          expires: Wed, 29 Dec 2021 07:19:28 GMT
          
          我是在2021-12-22 12:30左右 請(qǐng)求的 https://www.baidu.com/ ,
          返回的 expires 內(nèi)容如上。
          表示資源在 2012-12-29 07:12:28 過(guò)期,在這之前不會(huì)向服務(wù)器發(fā)送請(qǐng)求

          這個(gè)方式你看有毛病嗎?潛藏了一個(gè)大坑,如果電腦的本地時(shí)間與服務(wù)器時(shí)間不一致時(shí),那么服務(wù)器返回的這個(gè)過(guò)期時(shí)間可能就是不準(zhǔn)確的,因此這種方式在 HTTP 1.1 中被拋棄了。

          Cache-Control

          在 HTTP1.1 中,采用了一個(gè)非常關(guān)鍵的字段:Cache-Control 。這個(gè)字段也存在于響應(yīng)頭中。如:

          cache-control: max-age=2592000

          代表的是這個(gè)響應(yīng)返回后,在 (2592/3600=720小時(shí))直接可以直接使用緩存。

          它和 Expires 本質(zhì)的不同在于它并沒(méi)有采用具體的時(shí)間點(diǎn),而是采用的時(shí)長(zhǎng)來(lái)控制強(qiáng)緩存。如果 Expires 和 Cache-Control 同時(shí)存在的時(shí)候,Cache-Control 會(huì)優(yōu)先考慮。

          強(qiáng)緩存有沒(méi)有可能失效呢?如果資源緩存時(shí)間超時(shí),也就是強(qiáng)緩存失效了,接下來(lái)該怎么辦呢?此時(shí)就會(huì)進(jìn)入到第二級(jí)屏障 -- 協(xié)商緩存。

          3.2、協(xié)商緩存

          強(qiáng)緩存失效之后,瀏覽器在請(qǐng)求頭中攜帶相應(yīng)的 緩存tag 向服務(wù)器發(fā)送請(qǐng)求,服務(wù)器根據(jù)這個(gè) 緩存tag 決定到底是否使用緩存,這就是協(xié)商緩存

          緩存 tag 有兩種:ETag 和 Last-Modified 。

          ETag 是服務(wù)器根據(jù)當(dāng)前文件內(nèi)容生成的唯一標(biāo)識(shí),如果內(nèi)容發(fā)生更新,唯一標(biāo)識(shí)也會(huì)更新。瀏覽器接收到的 ETag 會(huì)作為 if-None-Match 字段的內(nèi)容,并放到請(qǐng)求頭中,發(fā)送給服務(wù)器之后,服務(wù)器會(huì)與服務(wù)器上的 值進(jìn)行對(duì)比,如果兩者一樣,瀏覽器直接返回304,使用緩存。不一樣時(shí)發(fā)送 http 請(qǐng)求。

          Last-Modified ,最后修改時(shí)間。瀏覽器第一次發(fā)送網(wǎng)絡(luò)請(qǐng)求后,服務(wù)器會(huì)在響應(yīng)頭上加上該字段。瀏覽器再發(fā)請(qǐng)求時(shí),會(huì)把該值作為 last-Modified-Since 的值,放入請(qǐng)求頭,然后服務(wù)器會(huì)與服務(wù)器上的最后修改時(shí)間進(jìn)行對(duì)比,如果兩者一樣,瀏覽器直接返回304,使用緩存。不一樣時(shí)發(fā)送 http 請(qǐng)求。

          兩者對(duì)比:

          精準(zhǔn)度上 ETag 更好一點(diǎn)。因?yàn)?ETag 能夠更準(zhǔn)確的判斷資源是否有更新,保證拉取到的都是最新內(nèi)容。

          性能上 Last-Modified 剛好一點(diǎn),只需要記錄一個(gè)時(shí)間點(diǎn)就好了。

          如果兩者都存在的話,優(yōu)先考慮 ETag。

          3.3、緩存位置

          前邊講述,瀏覽器請(qǐng)求地址時(shí),服務(wù)器返回 304 表示使用瀏覽器緩存,這些資源究竟緩存到哪了呢?

          緩存位置一共有四種,按照優(yōu)先級(jí)由高到低排列分別為:

          • Service Worker
          • Memory Cache
          • Disk Cache
          • Push Cache

          四、瀏覽器的本地存儲(chǔ)有哪些?

          所謂本地存儲(chǔ),就是把一些信息,存儲(chǔ)到客戶端本地,存儲(chǔ)的信息不會(huì)因?yàn)轫?yè)面的跳轉(zhuǎn)或關(guān)閉而消失。瀏覽器本地存儲(chǔ)主要分為:cookie、webStorage 和 indexDB。

          4.1、cookie

          cookie 主要為了辨別用戶身份。彌補(bǔ) http 在狀態(tài)管理上的不足。

          http 是一個(gè)無(wú)狀態(tài)協(xié)議,瀏覽器向服務(wù)器發(fā)送請(qǐng)求之后,服務(wù)器返回響應(yīng),下次再請(qǐng)求的時(shí)候,服務(wù)器已經(jīng)不認(rèn)識(shí)瀏覽器了,如果瀏覽器下次再發(fā)送請(qǐng)求時(shí),能夠把 cookie 帶上,服務(wù)器進(jìn)行解析,便能夠辨別瀏覽器的身份。

          cookie 就是用來(lái)存儲(chǔ)狀態(tài)的,它的特點(diǎn)分別有:

          • 能夠兼容所有瀏覽器,它和服務(wù)器之間有一定的關(guān)聯(lián)。
          • 存儲(chǔ)大小限制:一般瀏覽器規(guī)定同源下最多只能存儲(chǔ) 4KB 大小
          • cookie 存在過(guò)期時(shí)間,過(guò)期時(shí)間可以自己設(shè)置。
          • cookie 不穩(wěn)定,清除瀏覽器緩存或三方清理垃圾時(shí)容易把 cookie 移除掉。
          • 用戶可以根據(jù)句自己的需求開(kāi)啟 cookie 緩存,如果開(kāi)啟無(wú)痕瀏覽器或隱身模式時(shí),將關(guān)閉 cookie。

          4.2、webStorage

          webStorag 可分為 localStorage 和 sessionStorage ,是本地持久化存儲(chǔ),本地持久化存儲(chǔ)用來(lái)保存一些不需要發(fā)送給服務(wù)器的信息,用來(lái)補(bǔ)充 cookie 存儲(chǔ)方式不足。

          localStorage 特點(diǎn):

          • 不兼容低版本瀏覽器 IE6-8 。
          • 生命周期是永久的,除非用戶主動(dòng)清除,否則一直存在。
          • 存儲(chǔ)的數(shù)據(jù)大小一般為 5M,各瀏覽器之間有差異。
          • 不受瀏覽器無(wú)痕模式或隱身模式影響。
          • 嚴(yán)格的本地存儲(chǔ),與服務(wù)器之間沒(méi)有關(guān)系。

          sessionStorage 特點(diǎn):

            • 不兼容低版本瀏覽器 IE6-8 。
            • 僅在當(dāng)前會(huì)話下有效,關(guān)閉當(dāng)前頁(yè)面或關(guān)閉瀏覽器,就會(huì)被清除。
            • 存儲(chǔ)的數(shù)據(jù)大小一般為 5M,各瀏覽器之間有差異。
            • 嚴(yán)格的本地存儲(chǔ),與服務(wù)器之間沒(méi)有關(guān)系。

          localStorage 和 sessionStorage 有一個(gè)本質(zhì)區(qū)別,localStorage 生命周期是永久化的,而 sessionStorage 只存在于當(dāng)前會(huì)話。

          4.3、indexedDB

          indexedDB 是 html5 提供的一種本地存儲(chǔ),一般保存大量用戶數(shù)據(jù)并要求數(shù)據(jù)之間有搜索需要的場(chǎng)景,當(dāng)網(wǎng)絡(luò)斷開(kāi),做一些離線應(yīng)用,數(shù)據(jù)格式為 json 。本質(zhì)上是一個(gè) 非關(guān)系型數(shù)據(jù)庫(kù)。它的容量是沒(méi)有上限的。

          特點(diǎn):

          • 存儲(chǔ)空間較大,默認(rèn)250M 。
          • 鍵值對(duì)操作,可以進(jìn)行數(shù)據(jù)庫(kù)讀取和遍歷,也可以用索引進(jìn)行高效的檢索。
          • 受同源策略限制,無(wú)法跨域訪問(wèn)數(shù)據(jù)庫(kù)。

          總結(jié):瀏覽器本地存儲(chǔ)每種方式都有各自的特點(diǎn),cookie 比較小適合存儲(chǔ)與服務(wù)器之間通信的較小狀態(tài)信息,webStorage 存儲(chǔ)不參與服務(wù)器通信的數(shù)據(jù),indexedDB 存儲(chǔ)大型的非關(guān)系型數(shù)據(jù)庫(kù)。

          五、什么是 XSS 攻擊?

          XSS ( Cross Site Scripting ) 跨站腳本,為了與 CSS 區(qū)分,故意叫做 XSS 。主要是由于網(wǎng)站程序員對(duì)用戶輸入過(guò)濾不足,導(dǎo)致攻擊者利用輸入可以在頁(yè)面進(jìn)行顯示或盜取用戶信息,利用身份信息進(jìn)行惡意操作的一種攻擊方式。

          講直白點(diǎn),就是惡意攻擊者通過(guò)在輸入框處添加惡意 script 代碼,用戶瀏覽網(wǎng)頁(yè)的時(shí)候執(zhí)行 script 代碼,從而達(dá)到惡意攻擊用戶的目的。

          5.1、XSS 攻擊類型

          XSS 攻擊實(shí)現(xiàn)有三種方式:存儲(chǔ)型、反射型 和 文檔寫(xiě)。

          存儲(chǔ)型

          表面意思理解,就是將惡意腳本存儲(chǔ)起來(lái)。將腳本存儲(chǔ)到服務(wù)器的數(shù)據(jù)庫(kù),然后在客戶端執(zhí)行這些惡意腳本,從而達(dá)到攻擊效果。

          比如,在評(píng)論區(qū)提交一段 script 代碼,如果前后端不做任何轉(zhuǎn)義工作,直接把腳本存儲(chǔ)到數(shù)據(jù)庫(kù),頁(yè)面加載數(shù)據(jù)的時(shí)候,渲染時(shí)發(fā)現(xiàn)它是 js 代碼,就會(huì)直接執(zhí)行,相當(dāng)于執(zhí)行了一段未知邏輯的 js 。

          反射型

          反射型 XSS 指的是惡意腳本作為網(wǎng)絡(luò)請(qǐng)求的一部分。

          瀏覽器請(qǐng)求接口如:

          http://www.xxx.com?q=<script>alert("惡意腳本")</script>

          會(huì)將參數(shù) q=<script>alert("惡意腳本")</script> 傳遞給服務(wù)器,服務(wù)器將內(nèi)容返回給瀏覽器,瀏覽器渲染時(shí),發(fā)現(xiàn)它是 js 腳本,就會(huì)直接執(zhí)行。所以頁(yè)面一加載的時(shí)候,就會(huì)有一個(gè)彈框。

          之所以稱為反射型,是因?yàn)樗菑臑g覽器通過(guò)網(wǎng)絡(luò)請(qǐng)求經(jīng)過(guò)服務(wù)器,然后又返回瀏覽器,執(zhí)行解析。

          文檔型

          文檔型的 XSS 攻擊不會(huì)經(jīng)過(guò)服務(wù)器,作為中間人的角色,在數(shù)據(jù)傳輸過(guò)程中劫持到網(wǎng)絡(luò)數(shù)據(jù)包,然后修改里面的 html 文檔。

          常見(jiàn)的 wifi 劫持 或者本地惡意軟件。

          XSS 攻擊危害包括:

          • 盜取用戶各類賬號(hào),如機(jī)器登錄賬號(hào),用戶網(wǎng)銀,各類管理員賬號(hào)。
          • 控制企業(yè)數(shù)據(jù),包括讀取,篡改、添加、刪除敏感數(shù)據(jù)。
          • 盜竊具有商業(yè)價(jià)值的資料。
          • 控制受害者機(jī)器向其他網(wǎng)站發(fā)起攻擊。
          • 劫持別人的廣告,點(diǎn)擊廣告之后跳轉(zhuǎn)到自己的廣告頁(yè)

          5.2、XSS防范措施

          措施1:XSS 攻擊原理就是惡意執(zhí)行 js 腳本,我們要防范它,只需要在用戶輸入的地方,對(duì)輸入的內(nèi)容進(jìn)行轉(zhuǎn)碼或過(guò)濾。

          如:
          <script>
            alert('惡意腳本')
          </script>
          
          //轉(zhuǎn)碼后
          <script>alert('惡意腳本')</script>

          這樣在代碼 html 中解析時(shí),不會(huì)當(dāng)做 js 腳本執(zhí)行。

          措施2:CSP ,瀏覽器中的內(nèi)容安全策略,就是決策瀏覽器加載哪些資源。具體的有:

          • 同源策略,限制其他域下的資源加載。
          • 禁止在當(dāng)前頁(yè)面向其他域下提交數(shù)據(jù)。
          • 提供上報(bào)機(jī)制,能夠及時(shí)發(fā)現(xiàn) XSS 攻擊。

          措施3:HttpOnly,如果 cookie 設(shè)置了 httponly,那么通過(guò) js 腳本無(wú)法獲取到 cookie 信息。這樣能夠有效防止 XSS 攻擊,竊取用戶信息。

          六、http 和 https

          瀏覽器訪問(wèn) http 的網(wǎng)站的時(shí)候,域名前面會(huì)提示“不安全”,訪問(wèn) https//xxx.com 的時(shí)候?yàn)g覽器提示 “安全”,這是為什么呢?

          http 協(xié)議,超文本傳輸協(xié)議,被用于在服務(wù)器和瀏覽器之間傳遞信息,http協(xié)議以明文方式發(fā)送內(nèi)容,不提供任何方式的數(shù)據(jù)加密,如果攻擊者直接截取瀏覽器和服務(wù)器之間傳輸報(bào)文,就可以直接讀懂其中的信息。

          為了解決 http 協(xié)議的缺陷,使用 https 安全套接字層超文本傳輸協(xié)議,為了保證數(shù)據(jù)的安全性,在 http 協(xié)議的基礎(chǔ)上,新增了 SSL 協(xié)議,SSL依靠證書(shū)來(lái)驗(yàn)證服務(wù)器的身份器,并未瀏覽器和服務(wù)器之間的通信加密。

          https 并不是一個(gè)新協(xié)議,而是一個(gè)加強(qiáng)版的 http 。簡(jiǎn)單講 https 協(xié)議由 SSL+http 協(xié)議構(gòu)建成可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,要比 http 協(xié)議安全。

          https 和 http 的區(qū)別:

          • https 協(xié)議需要申請(qǐng)安全證書(shū),一般免費(fèi)較少,需要費(fèi)用,而 http 不需要。
          • https 具有 SSL 加密傳輸,更加安全,而 http 是明文傳輸,不安全。
          • https 和 http 使用的不同連接方式,用的默認(rèn)端口不一樣,http 是 80,https是443。
          • http 的連接簡(jiǎn)單,沒(méi)有狀態(tài),而 https 是需要通過(guò) SSL 校驗(yàn)身份信息的,相對(duì)更加安全。

          https 工作原理圖:

          加解密過(guò)程

          接著我們來(lái)談?wù)劄g覽器和服務(wù)器進(jìn)行協(xié)商加解密的過(guò)程。

          首先,瀏覽器會(huì)給服務(wù)器發(fā)送一個(gè)隨機(jī)數(shù)client_random和一個(gè)加密的方法列表。

          服務(wù)器接收后給瀏覽器返回另一個(gè)隨機(jī)數(shù)server_random和加密方法。

          現(xiàn)在,兩者擁有三樣相同的憑證: client_random、server_random和加密方法。

          接著用這個(gè)加密方法將兩個(gè)隨機(jī)數(shù)混合起來(lái)生成密鑰,這個(gè)密鑰就是瀏覽器和服務(wù)端通信的暗號(hào)。


          主站蜘蛛池模板: 日韩精品一区二区午夜成人版| 亚洲日本久久一区二区va| 日本无卡码免费一区二区三区| 久久蜜桃精品一区二区三区| 精品一区二区三区四区在线播放| 夜夜添无码一区二区三区| 亚洲国产精品一区二区久久hs| 91亚洲一区二区在线观看不卡| 亚洲av无码一区二区三区天堂古代| 国产一区二区三区小说| 国产成人精品一区二区三区| 日本精品一区二区三区在线观看| 亚洲国产一区在线| 日韩aⅴ人妻无码一区二区| 精品国产毛片一区二区无码| 久久人妻内射无码一区三区| 亚洲av无码一区二区三区天堂| 无码毛片一区二区三区中文字幕 | 无码人妻精品一区二区三区久久 | 一区二区在线免费视频| 日韩一区二区久久久久久| 亚洲国产精品无码第一区二区三区 | aⅴ一区二区三区无卡无码| 久久久av波多野一区二区| 国产成人一区二区三区免费视频 | 麻豆精品人妻一区二区三区蜜桃 | 免费播放一区二区三区| 国产成人一区二区精品非洲| 日韩精品一区二区三区中文| 国产精品亚洲一区二区三区 | 亚洲欧美国产国产一区二区三区| 亚洲一区日韩高清中文字幕亚洲| 精品国产一区二区三区色欲| 国产精品综合一区二区| 无码精品人妻一区二区三区人妻斩 | 日本精品无码一区二区三区久久久| 一区二区三区亚洲视频| 性色av无码免费一区二区三区| 亚洲AV本道一区二区三区四区| 日本一区二区三区中文字幕| 精品国产一区二区三区无码|