Pada artikel ini, saya menyelesaikan serangkaian publikasi di mana saya ingin berbicara tentang pengalaman saya menulis ekstensi web untuk browser. Saya sudah memiliki pengalaman membuat ekstensi web, yang dipasang oleh sekitar 100.000 pengguna Chrome, yang bekerja secara otonom, tetapi dalam seri artikel ini saya memutuskan untuk mempelajari proses pengembangan ekstensi web dengan mengintegrasikannya secara erat dengan sisi server.




Bagian 1 ,
Bagian 2 ,
Bagian 3Tugas Terjadwal
Ekstensi web memungkinkan Anda mengonfigurasi skrip khusus untuk secara otomatis menjalankan kode setelah halaman selesai memuat. Ini nyaman, misalnya, ketika Anda memiliki daftar halaman dengan tipe yang sama untuk merangkak dan menerima data dari eksekusi skrip. Atau jika Anda perlu menghapus iklan yang mengganggu di halaman mana pun di Internet, kode untuk melacak tindakan Anda di sumber daya web, ubah latar belakang halaman menjadi gelap, dll.
Dalam hal ini, seringkali perlu untuk menerima data dari halaman dalam mode jadwal harian. Misalnya, jika situs memiliki nilai tukar mata uang dan permintaan langsung oleh URL melindungi argumen hash. Sebagai salinan seperti itu, Anda dapat mempertimbangkan
situs web Bank Sentral Eropa . Dalam hal ini, untuk mendapatkan nilai tukar saat ini, Anda harus mengetahui URL hash untuk mendapatkan data yang benar dalam format XML.
Menggunakan ekstensi web, Anda dapat mengatur frekuensi yang diperlukan untuk menerima data melalui skrip untuk meminta nilai tukar. Ekstensi web menerima string dalam format mahkota sebagai input, oleh karena itu, untuk mendapatkan nilai tukar dalam mode harian, Anda harus menentukan * * / 1 * * *.
Dari sudut pandang teknis, bagian server memulai Puppeteer dengan penambahan skrip pengguna ke halaman browser Chromium. Dalam kasus ini, kita dihadapkan dengan masalah shutdown yang disengaja dari proses Chromium dari waktu ke waktu, karena peningkatan jumlah proses akan mempengaruhi kinerja keseluruhan sisi server. Jika Anda berencana untuk menjalankan skrip pengguna dalam mode berkala untuk menyelesaikan masalah di atas, Anda harus mengirim permintaan dari skrip pengguna ke Puppeteer untuk menyelesaikan proses Chromium.
Setelah tes panjang dari proses implementasi penjadwal tugas, diputuskan untuk melacak output dari konsol skrip. Jadi, untuk menghentikan proses Chromium, skrip pengguna harus memiliki perintah untuk menghentikan proses di bagian kode yang diperlukan:
console.log('script is ended');
Dengan menggunakan perintah ini, skrip pengguna dapat menutup proses server Chromium yang dihasilkan oleh Puppeteer. Ini diterapkan dengan melacak peristiwa "konsol" Puppeteer:
Jika skrip pengguna tidak memiliki perintah seperti itu, untuk menyelesaikan proses eksekusi dalam mode penjadwal tugas, Anda harus menghentikan penghitung waktu secara paksa. Ini diimplementasikan dengan cara sederhana menggunakan setTimeout:
const timeLimitCron = 30; const timeout = setTimeout(async () => { if(browser) { await browser.close(); } clearTimeout(timeout); }, timeLimitCron * 1000 );
Karena penjadwal tugas berjalan di sisi server, dan pengguna sering perlu menggunakan alamat IP tertentu, opsi untuk menggunakan server proxy telah ditambahkan.

Pengguna juga dapat mengunduh log pesan terbaru dari konsol Puppeteer. Misalnya, akan lebih mudah untuk memeriksa operasi yang benar dari server proxy.
Pintasan keyboard
Selama pengujian dan pengujian lapangan, ternyata untuk beberapa jenis skrip, penting untuk memiliki hot key untuk dieksekusi pada sumber daya web. Contoh skrip tersebut adalah Redability.js. Skrip ini menciptakan "tampilan bersih" untuk membaca konten situs. Yaitu, perpustakaan js menganalisis struktur halaman dengan konten dan memungkinkan Anda untuk mendapatkan dengan kemungkinan besar judul, penulis, dan konten halaman. Setelah itu, skrip pengguna dapat menimpa html sumber daya web dan memungkinkan pengguna untuk membaca dalam "bentuk murni", tanpa markup yang tidak perlu, iklan, dll.
Awalnya, menjalankan skrip pengguna hanya dimungkinkan dari ekstensi web pop-up dengan mengklik tombol "Jalankan". Logika interaksi dengan antarmuka ini sering dibenarkan dengan pertimbangan keamanan. Tetapi dalam contoh di atas, itu tidak memungkinkan Anda untuk dengan mudah membawa konten sumber daya web ke "bentuk murni."
Seperti dijelaskan di atas, ekstensi web memungkinkan Anda untuk bekerja dengan DOM melalui content.js, tetapi objek jendela tidak dapat digunakan, misalnya, untuk menyimpan parameter, karena itu bukan objek jendela dari tab terbuka. Kondisi ini membatasi pengoperasian ekstensi web sebagai objek untuk melacak penekanan tombol.
Dalam masalah yang harus dipecahkan, perlu untuk mentransfer "hot keys" dari antarmuka ekstensi web ke sisi server untuk penyimpanan. Selanjutnya, setiap kali Anda memuat halaman sumber daya web, dapatkan daftar "kunci cepat" dan muat skrip pengguna setelah mengklik kombinasi yang benar.
Hotkeys.js digunakan sebagai perpustakaan untuk bekerja dengan tombol pintas.
Setelah menerima daftar tombol pintas dari sisi server, kode berikut dijalankan:
var hotKeysMap = {keys: [], id: []}; for(var i in data.response.data) { hotKeysMap.keys.push(data.response.data[i]['hotkeys']); hotKeysMap.id.push(data.response.data[i]["_id"]); } if(hotKeysMap.keys) { getScript("hotkeys.js", function() { var script = document.createElement("script"); script.setAttribute("class", "gCore-hotKeys"); script.setAttribute("data-endpoint", event.data.endPoint); script.setAttribute("data-token", event.data.token); script.setAttribute("data-userid", event.data.userId); script.innerHTML = "GChotKeys = JSON.parse(\"" + JSON.stringify(hotKeysMap).replace(/"/g, "\\\"") + "\");\n" + "hotkeys(GChotKeys.keys.join(','), function(event, handler) {" + " event.preventDefault();" + " localStorage.setItem('runHotKeysScript', GChotKeys.id[GChotKeys.keys.indexOf(handler.key)]);" + "});"; document.body.appendChild(script); }); }
Fungsi getScript menghasilkan kode html untuk tag skrip dan menulisnya ke halaman sumber daya web. Jadi, pada setiap halaman kami memiliki kemampuan untuk melacak penekanan tombol. Kita juga harus melewatkan array hotkey yang cocok dengan id skrip yang akan dieksekusi. Ini diimplementasikan dengan menambahkan kode html untuk tag skrip, yang isinya memulai variabel global untuk menyimpan array yang cocok dalam format JSON.
Telah disebutkan di atas bahwa ada masalah komunikasi antara halaman terbuka sumber daya web dan skrip ekstensi ekstensi konten. Js dari ekstensi web, yang digunakan untuk memanipulasi DOM. Dalam hal ini, Anda dapat menggunakan teknik sederhana untuk memeriksa nilai di localStorage, yang merupakan objek umum untuk dua titik interaksi yang disebutkan di atas.
Di content.js, Anda cukup memeriksa nilai localStorage sekali per detik dan melakukan manipulasi DOM yang sama seperti ketika mengklik tombol "Jalankan" di ekstensi web pop-up.
setInterval(function() { if(localStorage.getItem('runHotKeysScript')) {
Dengan demikian, teknik "kunci cepat" diimplementasikan, yang memungkinkan Anda untuk dengan cepat meluncurkan skrip pengguna menggunakan kekuatan pustaka internal untuk memecahkan masalah praktis.
Kesimpulan
Selama implementasi proyek ini, tugas-tugas praktis menulis integrasi antara bagian server berdasarkan meteor.js dan ekstensi web lintas-browser diselesaikan. Blok sandungan utama adalah SCP dan proses interaksi antara tiga komponen bagian klien - halaman terbuka di browser, script content.js dan background.js.
Saya berharap pengalaman saya akan membuatnya lebih mudah untuk menulis ekstensi web lintas-browser yang lebih khusus.
Di masa depan, direncanakan untuk melokalisasi ekstensi web dan menulis skrip yang bermanfaat bagi komunitas. Jika pembaca memiliki ide atau keinginan untuk membantu menulis skrip pengguna tersebut, silakan tulis dalam pesan pribadi.