網頁使用前端技術禁止選取/複製/列印功能實現 + 對應 Chrome 破解 [The web content protection and cracking]
網頁使用前端技術禁止選取/複製/列印功能實現 + 對應 Chrome 破解 [The web content protection and cracking]
資料來源:
防守:
chatgpt(設計一個禁止網頁) ~ https://chatgpt.com/s/t_68ec55deb4b081919d2efa3240292362
破解:
01.使用破解右鍵擴充功能(外掛) [Enable Right Click – 啟用右鍵點擊] ~ https://chromewebstore.google.com/detail/enable-right-click-%E2%80%93-%E5%95%9F%E7%94%A8%E5%8F%B3%E9%8D%B5/ilfikgmeiipcoplabgkaigpdooejkpom?hl=zh-TW&utm_source=ext_sidebar
02.使用網頁拍照擴充功能(外掛) [GoFullPage – Full Page Screen Capture] ~ https://chromewebstore.google.com/detail/gofullpage-full-page-scre/fdpohaocaechififmbbbbbknoalclacl?hl=zh-TW&utm_source=ext_sidebar
03.chrome 閱讀模式
GITHUB: https://github.com/jash-git/The-web-content-protection-and-cracking
防守測試網頁(HTML+CSS+JS)
<!DOCTYPE html> <html lang="zh-Hant"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>防止選取、複製、列印示範頁</title> <style> body { font-family: "Microsoft JhengHei", sans-serif; background: #f3f4f6; color: #222; margin: 0; padding: 40px; user-select: auto; } h1 { text-align: center; color: #246f9e; } section { background: white; margin: 20px auto; padding: 20px; border-radius: 12px; box-shadow: 0 0 6px rgba(0,0,0,0.1); max-width: 700px; } h3 { margin-top: 0; } .note { font-size: 14px; color: #555; } .kbd { background: #eee; border-radius: 4px; padding: 2px 5px; font-family: monospace; } button { background: #246f9e; color: white; border: none; border-radius: 6px; padding: 10px 16px; margin-top: 10px; cursor: pointer; } button:hover { background: #195c85; } .switch { display: flex; align-items: center; gap: 8px; } .switch input[type="checkbox"] { width: 20px; height: 20px; } /* 11. 禁止列印 */ @media print { body * { display: none !important; } body::before { content: "⚠️ 本頁內容禁止列印"; display: block; text-align: center; margin-top: 40vh; font-size: 24px; color: red; } } </style> </head> <body> <h1>防止選取、複製與列印範例</h1> <section> <h3>1. 禁止文字選取 (CSS user-select: none)</h3> <p class="note">開啟後將無法用滑鼠反白選取任何文字。</p> <label class="switch"><input type="checkbox" id="selToggle"> 啟用</label> </section> <section> <h3>2. 禁止滑鼠右鍵</h3> <p class="note">右鍵選單會被攔截。</p> <label class="switch"><input type="checkbox" id="ctxToggle"> 啟用</label> </section> <section> <h3>3. 禁止複製 (copy event)</h3> <p class="note">複製動作將被阻止。</p> <label class="switch"><input type="checkbox" id="copyToggle"> 啟用</label> </section> <section> <h3>4. 禁止剪下 (cut event)</h3> <label class="switch"><input type="checkbox" id="cutToggle"> 啟用</label> </section> <section> <h3>5. 禁止貼上 (paste event)</h3> <label class="switch"><input type="checkbox" id="pasteToggle"> 啟用</label> </section> <section> <h3>6. 禁止拖曳 (dragstart event)</h3> <label class="switch"><input type="checkbox" id="dragToggle"> 啟用</label> </section> <section> <h3>7. 禁止檢視原始碼 / 快捷鍵 (Ctrl+U, Ctrl+S, F12, Ctrl+Shift+I)</h3> <label class="switch"><input type="checkbox" id="keyToggle"> 啟用</label> </section> <section> <h3>8. 禁止開啟 DevTools(持續偵測)</h3> <p class="note">使用簡單的 console 偵測方式。</p> <label class="switch"><input type="checkbox" id="devToggle"> 啟用</label> </section> <section> <h3>9. 禁止全選 (Ctrl+A)</h3> <label class="switch"><input type="checkbox" id="selAllToggle"> 啟用</label> </section> <section> <h3>10. 全部啟用 / 清除</h3> <button id="applyAll">全部啟用</button> <button id="clearAll">全部清除</button> </section> <section> <h3>11. 禁止列印(CSS + JS)</h3> <p class="note">當使用者按 <span class="kbd">Ctrl/Cmd + P</span> 或列印時,將顯示提示並阻止列印。</p> <label class="switch"><input type="checkbox" id="printToggle"> 啟用禁止列印</label> </section> <script> // 1. 禁止選取 const selToggle = document.getElementById('selToggle'); selToggle.addEventListener('change', e=>{ document.body.style.userSelect = e.target.checked ? 'none' : 'auto'; }); // 2. 禁止右鍵 const ctxToggle = document.getElementById('ctxToggle'); let ctxHandler=null; ctxToggle.addEventListener('change', e=>{ if(e.target.checked){ ctxHandler=(ev)=>{ev.preventDefault();}; document.addEventListener('contextmenu', ctxHandler); } else { document.removeEventListener('contextmenu', ctxHandler); } }); // 3. 禁止複製 const copyToggle=document.getElementById('copyToggle'); let copyHandler=null; copyToggle.addEventListener('change', e=>{ if(e.target.checked){ copyHandler=(ev)=>{ev.preventDefault(); alert('禁止複製');}; document.addEventListener('copy', copyHandler); } else document.removeEventListener('copy', copyHandler); }); // 4. 禁止剪下 const cutToggle=document.getElementById('cutToggle'); let cutHandler=null; cutToggle.addEventListener('change', e=>{ if(e.target.checked){ cutHandler=(ev)=>{ev.preventDefault(); alert('禁止剪下');}; document.addEventListener('cut', cutHandler); } else document.removeEventListener('cut', cutHandler); }); // 5. 禁止貼上 const pasteToggle=document.getElementById('pasteToggle'); let pasteHandler=null; pasteToggle.addEventListener('change', e=>{ if(e.target.checked){ pasteHandler=(ev)=>{ev.preventDefault(); alert('禁止貼上');}; document.addEventListener('paste', pasteHandler); } else document.removeEventListener('paste', pasteHandler); }); // 6. 禁止拖曳 const dragToggle=document.getElementById('dragToggle'); let dragHandler=null; dragToggle.addEventListener('change', e=>{ if(e.target.checked){ dragHandler=(ev)=>{ev.preventDefault();}; document.addEventListener('dragstart', dragHandler); } else document.removeEventListener('dragstart', dragHandler); }); // 7. 禁止快捷鍵 const keyToggle=document.getElementById('keyToggle'); let keyHandler=null; keyToggle.addEventListener('change', e=>{ if(e.target.checked){ keyHandler=(ev)=>{ const k=ev.key.toLowerCase(); if(ev.ctrlKey && ['u','s','a','c'].includes(k)){ev.preventDefault();} if(ev.key==='F12' || (ev.ctrlKey&&ev.shiftKey&&['i','j','c'].includes(k))){ev.preventDefault();} }; document.addEventListener('keydown', keyHandler,true); } else document.removeEventListener('keydown', keyHandler,true); }); // 8. DevTools 偵測 const devToggle=document.getElementById('devToggle'); let devInterval=null; devToggle.addEventListener('change', e=>{ if(e.target.checked){ const element=new Image(); Object.defineProperty(element,'id',{get:function(){ alert('⚠️ 偵測到開發者工具,請關閉。'); throw new Error("DevTools detected"); }}); devInterval=setInterval(()=>{console.log(element);},1000); } else clearInterval(devInterval); }); // 9. 禁止 Ctrl+A const selAllToggle=document.getElementById('selAllToggle'); let selAllHandler=null; selAllToggle.addEventListener('change', e=>{ if(e.target.checked){ selAllHandler=(ev)=>{if(ev.ctrlKey&&ev.key.toLowerCase()==='a'){ev.preventDefault();}}; document.addEventListener('keydown', selAllHandler,true); } else document.removeEventListener('keydown', selAllHandler,true); }); // 11. 禁止列印 const printToggle = document.getElementById('printToggle'); let printKeyHandler = null; let beforePrintHandler = null; printToggle.addEventListener('change', (e)=>{ if(e.target.checked){ // 攔截 Ctrl+P / Cmd+P printKeyHandler = (ev)=>{ const key = ev.key?.toLowerCase(); if((ev.ctrlKey || ev.metaKey) && key === 'p'){ ev.preventDefault(); alert('⚠️ 本頁內容禁止列印'); return false; } }; document.addEventListener('keydown', printKeyHandler, true); // 攔截 beforeprint beforePrintHandler = ()=>{ alert('⚠️ 本頁內容禁止列印'); window.stop(); document.body.innerHTML = '<div style="text-align:center;margin-top:40vh;font-size:24px;color:red;">⚠️ 本頁內容禁止列印</div>'; }; window.addEventListener('beforeprint', beforePrintHandler); } else { document.removeEventListener('keydown', printKeyHandler, true); window.removeEventListener('beforeprint', beforePrintHandler); printKeyHandler = null; beforePrintHandler = null; } }); // 10. 全部啟用 / 清除 const applyAll=document.getElementById('applyAll'); const clearAll=document.getElementById('clearAll'); applyAll.addEventListener('click', ()=>{ document.querySelectorAll('input[type=checkbox]').forEach(c=>{c.checked=true;c.dispatchEvent(new Event('change'));}); }); clearAll.addEventListener('click', ()=>{ document.querySelectorAll('input[type=checkbox]').forEach(c=>{c.checked=false;c.dispatchEvent(new Event('change'));}); }); </script> </body> </html>
破解工具截圖
PS.5W2H1R 延伸發想 ~ 朗讀模式+錄音筆就可以得到語音檔方便無網路/無法閱讀時(EX:閱讀障礙)使用