<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>View Source — Cara Melihat Kode Sumber Halaman Web</title>
<style>
#vsBox{font-family:monospace;background:#111;color:#e6e6e6;padding:12px;border-radius:8px}
#vsControls{display:flex;gap:8px;margin-bottom:8px;flex-wrap:wrap}
#vsBox textarea{width:100%;height:100vh;background:#0b0b0b;color:#dcdcdc;border:1px solid #222;padding:8px;resize:vertical}
#vsControls input[type=text]{flex:1;min-width:180px;padding:8px;border-radius:6px;border:1px solid #333;background:#0f0f0f;color:#fff}
.button{padding:8px 10px;border-radius:6px;border:none;cursor:pointer}
.btn-primary{background:#1e88e5;color:#fff}
.btn-plain{background:#2b2b2b;color:#fff}
.small{font-size:12px;padding:6px 8px}
</style>
</head>
<body>
<header>View Source HTML</header>
<div id="vsBox">
<div id="vsControls">
<input id="vsUrl" type="text" placeholder="Masukkan URL (opsional, kosong = halaman ini)">
<button id="vsLoad" class="button btn-primary small">Tampilkan Source</button>
<button id="vsCopy" class="button btn-plain small">Copy</button>
<button id="vsDownload" class="button btn-plain small">Download .html</button>
<label style="align-self:center;font-size:12px;margin-left:6px;color:#bbb">Note: fetch eksternal butuh proxy/CORS.</label>
</div>
<textarea id="vsArea" readonly spellcheck="false">Tekan "Tampilkan Source" untuk mulai...</textarea>
</div>
<script>
(function(){
const area = document.getElementById('vsArea');
const urlInput = document.getElementById('vsUrl');
const loadBtn = document.getElementById('vsLoad');
const copyBtn = document.getElementById('vsCopy');
const dlBtn = document.getElementById('vsDownload');
function show(text){
area.value = text;
area.scrollTop = 0;
}
function getThisPageSource(){
// ambil source DOM sebagai HTML terformat
const doctype = document.doctype ? new XMLSerializer().serializeToString(document.doctype) + '\n' : '';
const html = document.documentElement.outerHTML;
return doctype + html;
}
async function fetchUrl(u){
try {
const res = await fetch(u, {method:'GET', mode:'cors'});
if(!res.ok) throw new Error(res.status + ' ' + res.statusText);
const text = await res.text();
return text;
} catch(e){
throw e;
}
}
loadBtn.addEventListener('click', async ()=>{
const raw = urlInput.value.trim();
if(!raw){
show('Loading source halaman ini...\n\n');
try{
const src = getThisPageSource();
show(src);
}catch(e){
show('Error saat ambil source halaman ini: ' + e.message);
}
return;
}
// kalau user minta URL eksternal — CORS berlaku
// saran: gunakan proxy seperti https://api.allorigins.win/raw?url= atau CORS-Proxy sendiri
let target = raw;
// jika bukan http(s) maka tambahkan https://
if(!/^https?:\/\//i.test(target)) target = 'https://' + target;
show('Mengambil: ' + target + '\n\n(Perhatian: Jika server target menolak CORS, gunakan proxy seperti https://api.allorigins.win/raw?url= atau server proxy sendiri)\n\n');
// coba langsung dulu; jika gagal, user bisa gunakan proxy
try {
const txt = await fetchUrl(target);
show(txt);
} catch (err) {
show('Gagal langsung ambil: ' + err.message + '\n\nMencoba via proxy public allorigins...');
// fallback ke allorigins
try {
const proxy = 'https://api.allorigins.win/raw?url=' + encodeURIComponent(target);
const txt2 = await fetchUrl(proxy);
show(txt2);
} catch (err2) {
show('Gagal ambil via proxy juga: ' + err2.message + '\n\nSolusi: pakai proxy/CORS-own server atau ambil source server-side.');
}
}
});
copyBtn.addEventListener('click', ()=>{
area.select();
try{
document.execCommand('copy');
copyBtn.textContent = 'Copied ✓';
setTimeout(()=> copyBtn.textContent = 'Copy',1200);
}catch(e){
copyBtn.textContent = 'Copy failed';
setTimeout(()=> copyBtn.textContent = 'Copy',1200);
}
});
dlBtn.addEventListener('click', ()=>{
const blob = new Blob([area.value], {type:'text/html'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = (document.title||'source') + '.html';
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
});
})();
</script>
</body>
</html>

No comments:
Post a Comment