使用Web?Component實現(xiàn)防篡改水印
這篇文章的關鍵可以分為3個部分,Web Component + 防篡改 + 水印生成。在使用Web Component之前,我已經(jīng)通過MutationObserver實現(xiàn)了防篡改水印的第一版。但在了解到Web Component的特性之后,我認為也許用Web Component也不錯,因為Web Component內部有鉤子天然支持被篡改時被觸發(fā),用來防篡改非常方便。下面也會對MutationObserver與Web Component的實現(xiàn)做比較。
設計目標
設計一個hook用于插入水印至ref指定的組件中,被插入的水印節(jié)點應當不可篡改。
const { data: username } = useRequest(...) const ref = useWatermark(username); // 水印組件會插入ref.current對應的DOM節(jié)點 return <div ref={ref}> {children} </div>
水印生成原理
創(chuàng)建一個div節(jié)點,將背景設置為一個透明的水印圖片,將z-index設置為10000疊加在站點上即可實現(xiàn)水印效果。
生成水印圖
水印圖可以在前端直接生成,可以使用canvas通過命令繪制,或預聲明svg字符串。我選用的是svg字符串生成,因為使用svg清晰度較高,也比較簡單。將svgString定義好,再轉換成base64即可。
const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="146px"> <text x="10px" y="73px" text-anchor="start" transform="rotate(-20 0 73)" fill="rgba(40, 47, 56, 0.03)" font-weight="500" font-size="14" font-family="Helvetica Neue,Helvetica,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,WenQuanYi Micro Hei,sans-serif" > ${content} </text> <text x="210px" y="146px" text-anchor="start" transform="rotate(-20 200 146)" fill="rgba(40, 47, 56, 0.03)" font-weight="500" font-size="14" font-family="Helvetica Neue,Helvetica,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,WenQuanYi Micro Hei,sans-serif" > ${content} </text> </svg>`; const background = 'data:image/svg+xml;base64,' + window.btoa(svgString);
CSS與DIV布局
注意所有CSS都應該直接定義在div節(jié)點上,并且加上!important,這樣能有效避免樣式被覆蓋。
position: absolute !important; top: 0px !important; right: 0px !important; bottom: 0px !important; left: 0px !important; overflow: hidden !important; display: block !important; opacity: 1 !important; z-index: 10000 !important; pointer-events: none !important; // 可以防止鼠標事件被水印節(jié)點攔截 background: url(${background});
const node = document.createElement('div'); watermarkRef.current = node; node.setAttribute( 'style', `position: absolute !important; top: 0px !important; right: 0px !important; bottom: 0px !important; left: 0px !important; overflow: hidden !important; display: block !important; opacity: 1 !important; z-index: 10000 !important; pointer-events: none !important; background: url(${background});` );
防篡改原理
MutationObserve
const observer = new MutationObserver(function (entries) { // 因為MutationObserve沒辦法監(jiān)聽自己的屬性是否被修改,自己是否被移除,只能監(jiān)聽父組件 // 通過對父組件觀測,entry.type = 'attributes'可以判斷水印節(jié)點的屬性是否被修改 // entry.type = 'childList' 可以判斷水印節(jié)點是否被移除 for (const entry of entries) { if ( (entry.type === 'attributes' && entry.target === watermarkRef.current) || (entry.type === 'childList' && Array.from(entry.removedNodes).includes(watermarkRef.current)) ) { removeWatermark(); generateWaterMark(); return; } } }); const config = { attributes: true, childList: true, subtree: true }; observer.observe( parentNode, // 水印掛載到的父組件 config );
Web Component
使用Web Component的好處就是可以直接綁定回調函數(shù),檢測自己是否被篡改或移除。
class WatermarkElement extends HTMLElement { static observedAttributes = ["style"]; // 需要觀測的屬性 constructor() { super(); } connectedCallback() { // 當組件掛載至dom中,可以用來初始化 } disconnectedCallback() { // 當組件從document中移除,用于檢測水印被刪除 } adoptedCallback() { // 當組件在document中被移動 // 若觸發(fā)則表示水印被移動,可能失效 } attributeChangedCallback(name, oldValue, newValue) { // 若觸發(fā)表示style屬性被操作,可能是惡意篡改 } } customElements.define("watermark-element", MyCustomElement);
到此這篇關于使用Web Component實現(xiàn)防篡改水印的文章就介紹到這了,更多相關Web Component防篡改水印內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
webpack結合express實現(xiàn)自動刷新的方法
這篇文章主要給大家介紹了關于webpack結合express實現(xiàn)自動刷新的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用webpack具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-05-05javascript編程開發(fā)中取色器及封裝$函數(shù)用法示例
這篇文章主要介紹了javascript編程開發(fā)中取色器及封裝$函數(shù),結合實例形式分析了javascript封裝$函數(shù)及數(shù)值運算、頁面元素動態(tài)操作實現(xiàn)取色器功能相關技巧,需要的朋友可以參考下2017-08-08