Panduan Safelink di Blog Utama (Versi Alternatif): Solusi Redirect Lebih Stabil

menit membaca.
Diperbarui
  • Panduan Safelink di Blog Utama

    Setelah melakukan pembaruan pada panduan Safelink yang memanfaatkan sessionStorage, kami menyadari kelemahan fatal dari metode ini yang membuat Safelink tidak bekerja ketika tautan dibuka di tab atau jendela baru. Dalam skenario tersebut, data session tidak ikut terbawa, sehingga proses redirect terhenti.

    Untuk menutupi celah ini, kami mengembangkan versi alternatif dengan pendekatan berbeda. Solusi yang dirancang untuk memastikan proses redirect tetap berjalan bagaimanapun cara pengunjung membuka tautan—baik di tab baru, jendela baru (new window), atau bahkan di browser yang berbeda.


    Menggunakan Parameter URL Base64

    Berbeda dengan versi sebelumnya, alternatif ini menyimpan informasi URL tujuan langsung di parameter tautan menggunakan format Base64.

    Hasilnya? SafeLink dapat bekerja secara konsisten di berbagai kondisi tanpa bergantung pada sesi browser.

    Base64 adalah metode mengubah data biner (seperti gambar, file) menjadi teks biasa (ASCII) agar aman dan mudah dikirim lewat sistem yang hanya mendukung teks, seperti email atau URL, dengan cara mengelompokkan bit data menjadi 6-bit dan memetakannya ke 64 karakter unik (A-Z, a-z, 0-9, +, /).

    Mengatasi URL yang Panjang

    Mungkin Anda khawtir penggunaan parameter Base64 akan membuat URL safelink terlihat panjang dan berantakan. Kabar baiknya, history.replaceState tetap dipertahankan pada versi ini.

    Begitu halaman safeLink dimuat, parameter rumit tersebut sekitika dihapus dari address bar. Dari sisi pengguna, URL safelink tetap terlihat bersih tanpa mengorbakan stabilitas fungsi.


    Kekurangan Metode Parameter URL Base64

    Meski lebih stabil dibandingkan sessionStorage, metode Base64 tetap memiliki beberapa keterbatasan yang perlu dipertimbangkan sebagai pembanding.

    • Base64 Bukan Enkripsi
      Metode ini hanyalah encoding standar, bukan enkripsi tingkat tinggi. Pengguna yang mahir tetap dapat melihat URL asli dengan melakukan decode secara manual.
    • Potensi Jejak di Riwayat Browser
      Karena parameter URL sempat muncul saat halaman pertama kali dimuat, ada kemungkinan URL Panjang tersebut tersimpan di riwayat browser pengguna sebelum dibersihkan.

    Dua Pilihan Kode Safelink

    Untuk menyesuaikan kebutuhan pengguna, kami menyediakan dua pendekatan berbeda dalam menangani tautan eksternal (outbound link), pilih yang paling sesuai dengan situs Anda.

    1. Tautan dengan className Khusus (Performa Maksimal)

    Metode ini sangat efisien karena kode hanya akan memproses tautan yang memiliki className tertentu (contoh: .safeurl). Ini sangat direkomendasikan jika ada banyak tautan dalam halaman namun hanya sebagian kecil yang ingin diarahkan ke laman SafeLink.

    Versi ini lebih ringan dan cepat karena tidak memindai seluruh tautan di halaman, bekerja dengan prinsip sederhana: Temukan .safeurl, proses. jika tidak ada, hentikan.

    const config = {
        safeID = 'safelink',
        safeURL: ['/p/safelink.html'],
        timer: 15,
        redirect: true,
        text: {
            wait: 'The link will appear in 0 second',
            direct: 'You’ll be redirected to the download link in 0 second',
            shifted: 'Redirecting... [link] if you’re not redirected automatically.',
            click: 'Click here',
            btn: 'Direct to link.'
        }
    };
    (() => {
        const randomURL = url => url[Math.floor(Math.random() * url.length)];
        const safeLink = () => config.safeURL.some(path => location.pathname.endsWith(path));
        const safeMessage = (text, time) => {
            const [start, end] = text.split('0');
            return `<p>${start} <span>${time} ${end}</span>.</p>`;
        };
        const outboundLinks = () => {
            const links = document.querySelectorAll('a.safeurl[href]');
            if (!links.length) return;
            links.forEach(anchor => {
                const encoded = encodeURIComponent(btoa(anchor.href));
                Object.assign(anchor, {
                    href: `${location.origin}${randomURL(config.safeURL)}?go=${encoded}`,
                    target: '_self',
                    rel: 'noopener'
                })
            })
        };
        const handleLink = () => {
            const params = new URLSearchParams(location.search);
            const encoded = params.get('go');
            if (!encoded) return;
            const link = atob(decodeURIComponent(encoded))
            params.delete('go');
            history.replaceState({}, '', location.pathname + (params.toString() ? '?' + params : ''));
            let counter = config.timer;
            const label = config.redirect ? config.text.direct : config.text.wait;
            const box = document.getElementById(config.safeID);
            if (!box) return;
            box.removeAttribute('hidden');
            box.innerHTML = safeMessage(label, counter);
            const countdown = setInterval(() => {
                counter--;
                box.innerHTML = safeMessage(label, counter);
                if (counter > 0) return;
                clearInterval(countdown);
    
                if (config.redirect) {
                    box.innerHTML = `<p>${config.text.shifted.replace('[link]', `<a href='${link}' target='_blank' rel='nofollow noopener noreferrer'>${config.text.click}</a>`)}</p>`;
                    location.href = link;
                } else {
                    box.innerHTML = '';
                    const btn = document.createElement('a');
                    //btn.className = 'btn';
                    btn.href = link;
                    btn.target = '_blank';
                    btn.rel = 'nofollow noopener noreferrer';
                    btn.innerHTML = `<span>${config.text.btn}</span>`;
                    box.appendChild(btn);
                }
            }, 1000)
        };
        safeLink() ? handleLink() : outboundLinks();
    })();

    Cara Penggunaan
    Tambahkan class='safeurl' pada tautan yang ingin dialihkan ke safelink. Contoh:

    <a class='safeurl' href='https://mega.nz'>Download File</a>
    2. Filter Berdasarkan Daftar Domain (Otomatis & Praktis)

    Jika Anda memiliki banyak postingan lama dan tidak ingin repot menambahkan class ke tautan eksternal satu per satu, metode ini adalah solusinya. Versi ini tetap memperahankan daftar processURL untuk menentukan tautan mana yang harus melewati safelink.

    Pendekatan ini cocok untuk:
    • Situs dengan banyak konten lama
    • Migrasi tanpa perlu mengedit setiap tautan secara manual
    const config = {
        safeID = 'safelink',
        safeURL: ['/p/safelink.html'],
        processURL: ['drive.google.com', 'mega.nz'],
        timer: 15,
        redirect: true,
        text: {
            wait: 'The link will appear in 0 second',
            direct: 'You’ll be redirected to the download link in 0 second',
            shifted: 'Redirecting... [link] if you’re not redirected automatically.',
            click: 'Click here',
            btn: 'Direct to link.'
        }
    };
    (() => {
        const randomURL = url => url[Math.floor(Math.random() * url.length)];
        const matchURL = href =>
            config.processURL.some(domain => href.includes(domain));
        const safeLink = () => config.safeURL.some(path => location.pathname.endsWith(path));
        const safeMessage = (text, time) => {
            const [start, end] = text.split('0');
            return `<p>${start} <span>${time} ${end}</span>.</p>`;
        };
        const outboundLinks = () => {
            const links = document.querySelectorAll('a[href]');
            if (!links.length) return;
            let found = false;
            links.forEach(anchor => {
                if (!matchURL(anchor.href)) return;
                const encoded = encodeURIComponent(btoa(anchor.href));
                found = true;
                Object.assign(anchor, {
                    href: `${location.origin}${randomURL(config.safeURL)}?go=${encoded}`,
                    target: '_self',
                    rel: 'noopener'
                })
            });
            if (!found) return
        };
        const handleLink = () => {
            const params = new URLSearchParams(location.search);
            const encoded = params.get('go');
            if (!encoded) return;
            let link;
            try {
                link = atob(decodeURIComponent(encoded))
            } catch {
                return
            };
            params.delete('go');
            history.replaceState({}, '', location.pathname + (params.toString() ? '?' + params : ''));
            let counter = config.timer;
            const label = config.redirect ? config.text.direct : config.text.wait;
            const box = document.getElementById(config.safeID);
            if (!box) return;
            box.removeAttribute('hidden');
            box.innerHTML = safeMessage(label, counter);
            const countdown = setInterval(() => {
                counter--;
                box.innerHTML = safeMessage(label, counter);
                if (counter > 0) return;
                clearInterval(countdown);
                if (config.redirect) {
                    box.innerHTML = `<p>${config.text.shifted.replace('[link]', `<a href='${link}' target='_blank' rel='nofollow noopener noreferrer'>${config.text.click}</a>`)}</p>`;
                    location.href = link;
                } else {
                    box.innerHTML = '';
                    const btn = document.createElement('a');
                    //btn.className = 'btn';
                    btn.href = link;
                    btn.target = '_blank';
                    btn.rel = 'nofollow noopener noreferrer';
                    btn.innerHTML = `<span>${config.text.btn}</span>`;
                    box.appendChild(btn);
                }
            }, 1000)
        };
        safeLink() ? handleLink() : outboundLinks();
    })();

    Alur Kerja Kode Safelink

    Secara garis besar, alur kerja versi alternatif ini masih sama dengan versi awal. Perbedaannya terletak pada cara penyimpanan dan pemrosesan URL tujuan.

    1. Inisiasi Tautan: Kode akan mencari tautan dengan class .safeurl atau mencocokkan tautan dengan daftar processURL, kemudian mengubah URL tujuan menjadi format Base64 yang disimpan sebagai parameter ?go=xxxx.
    2. Menangani Tautan: Saat halaman Safelink terbuka, kode mengambil data dari parameter tersebut. Di saat yang sama, history.replaceState bekerja menghapus parameter dari address bar untuk menjaga URL tetap bersih.
    3. Countdown & Redirect: Setelah URL dibersihkan, hitung mundur (countdown) dimulai. Pengguna akan dialihkan ke URL tujuan secara otomatis atau melalui tombol CTA (Call-to-Action), tergantung konfigurasi.

    Kesimpulan: Mana yang Terbaik untuk Anda?

    Tidak ada solusi yang benar-benar sempurna. Setiap metode memiliki keunggulan dan kekurangan masing-masing, namun keduanya menawarkan manfaat bagi SEO dan Otoritas Situs yang lebih kuat di mata mesin pencari melalui peningkatan pageviews dan penurutan Bounce Rate.

    • sessionStorage lebih mengutamakan User Experience (UX), cocok untuk Anda yang ingin URL selalu bersih sejak awal dan yakin pengunjung situs Anda jarang menggunakan fitur 'Open in New Tab'
    • Parameter URL Base64 Unggul dari sisi ketahanan system, menjadikannya pilihan terbaik jika pengunjung Anda lebih sering membuka tautan di banyak tab sekaligus, menjamin proses redirect tetap berjalan 100% dalam kondisi apapun.
    komentar