網頁使用前端技術禁止選取/複製/列印功能實現 + 對應 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:閱讀障礙)使用