網頁使用前端技術禁止選取/複製/列印功能實現 + 對應 Chrome 破解 [The web content protection and cracking]

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

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *