Jurutera hadapan semua tahu bahawa JavaScript mempunyai keupayaan pengendalian pengecualian asas. Kami boleh membuang Ralat baharu(), dan penyemak imbas juga akan membuang pengecualian apabila kami membuat ralat semasa memanggil API. Tetapi dianggarkan kebanyakan jurutera hadapan tidak pernah mempertimbangkan untuk mengumpul maklumat yang tidak normal ini
Bagaimanapun, selagi ralat JavaScript tidak muncul semula selepas menyegarkan, pengguna boleh menyelesaikan masalah dengan menyegarkan dan penyemak imbas tidak akan ranap. Andaian ini berlaku sebelum Apl Halaman Tunggal menjadi popular. Status Apl Halaman Tunggal semasa menjadi sangat rumit selepas dijalankan untuk tempoh masa Pengguna mungkin telah melakukan beberapa operasi input sebelum tiba di sini. Bukankah operasi sebelumnya sepatutnya dibuat semula sepenuhnya? Oleh itu, kami masih perlu menangkap dan menganalisis maklumat pengecualian ini, dan kemudian kami boleh mengubah suai kod untuk mengelak daripada menjejaskan pengalaman pengguna.
Cara menangkap pengecualian
Ralat baru lontaran() yang kami tulis sendiri pastinya boleh ditangkap jika kami mahu, kerana kami tahu dengan tepat di mana lontaran ditulis. Walau bagaimanapun, pengecualian yang berlaku apabila memanggil API penyemak imbas tidak semestinya mudah ditangkap Sesetengah API ditulis dalam piawaian untuk membuang pengecualian, dan sesetengah API hanya dilemparkan oleh penyemak imbas individu disebabkan oleh perbezaan pelaksanaan atau kecacatan. Untuk yang pertama, kita juga boleh menangkapnya melalui cuba-tangkap Untuk yang terakhir, kita mesti mendengar pengecualian global dan kemudian menangkapnya.
cuba tangkap
Jika sesetengah API penyemak imbas diketahui membuang pengecualian, maka kita perlu meletakkan panggilan dalam try-catch untuk menghalang keseluruhan program daripada memasuki keadaan haram akibat ralat. Sebagai contoh, window.localStorage ialah API sedemikian. Ia akan mengeluarkan pengecualian selepas menulis data melebihi had kapasiti Ini juga akan berlaku dalam mod penyemakan imbas peribadi.
Untuk kawasan yang tidak diliputi oleh try-catch, jika pengecualian berlaku, ia hanya boleh ditangkap melalui window.onerror.
Atribut hilang
Andaikan kami mempunyai fungsi reportError untuk mengumpul pengecualian yang ditangkap, dan kemudian menghantarnya ke storan sisi pelayan secara berkelompok untuk pertanyaan dan analisis, maka apakah maklumat yang ingin kami kumpulkan? Maklumat yang lebih berguna termasuk: jenis ralat (nama), mesej ralat (mesej), alamat fail skrip (skrip), nombor baris (baris), nombor lajur (lajur) dan surih tindanan (tindanan). Jika pengecualian ditangkap melalui cuba-tangkap, maklumat ini berada pada objek Ralat (disokong oleh penyemak imbas arus perdana), jadi reportError juga boleh mengumpul maklumat ini. Tetapi jika ia ditangkap melalui window.onerror, kita semua tahu bahawa fungsi acara ini hanya mempunyai 3 parameter, jadi maklumat yang tidak dijangka dari 3 parameter ini hilang.
Mesej bersiri
Jika objek Ralat dicipta oleh kami sendiri, maka error.message dikawal oleh kami. Pada asasnya, apa sahaja yang kita masukkan ke dalam error.message, parameter pertama (message) window.onerror ialah. (Penyemak imbas sebenarnya akan membuat sedikit pengubahsuaian, seperti menambah awalan 'Ralat Tidak Ditangkap:'.) Oleh itu, kita boleh mensirikan sifat yang kita sayangi (seperti JSON.Stringify) dan menyimpannya dalam error.message, dan kemudian membacanya dalam window.onerror Hanya keluarkan dan nyahserikannya. Sudah tentu, ini terhad kepada objek Ralat yang kita cipta sendiri.
Parameter kelima
Pengilang penyemak imbas juga mengetahui batasan yang dihadapi oleh orang ramai apabila menggunakan window.onerror, jadi mereka mula menambah parameter baharu pada window.onerror. Memandangkan hanya nombor baris tetapi tiada nombor lajur kelihatan tidak terlalu simetri, IE mula-mula menambah nombor lajur dan meletakkannya dalam parameter keempat. Walau bagaimanapun, semua orang lebih mengambil berat tentang sama ada mereka boleh mendapatkan tindanan lengkap, jadi Firefox berkata adalah lebih baik untuk meletakkan tindanan dalam parameter kelima. Tetapi Chrome berkata bahawa adalah lebih baik untuk meletakkan keseluruhan objek Ralat dalam parameter kelima Anda boleh membaca mana-mana sifat yang anda inginkan, termasuk sifat tersuai. Akibatnya, Chrome bergerak lebih pantas dan melaksanakan tetingkap baharu. tandatangan onerror dalam Chrome 30, yang menyebabkan draf standard ditulis dengan sewajarnya.
Nama atribut objek Ralat yang kami bincangkan sebelum ini adalah berdasarkan kaedah penamaan Chrome Walau bagaimanapun, penyemak imbas yang berbeza menamakan atribut objek Ralat secara berbeza Contohnya, alamat fail skrip dipanggil skrip dalam Chrome tetapi dipanggil nama fail dalam Firefox. . Oleh itu, kita juga memerlukan fungsi khas untuk menormalkan objek Ralat, iaitu, untuk memetakan nama atribut yang berbeza kepada nama atribut bersatu. Untuk kaedah khusus, sila rujuk artikel ini. Walaupun pelaksanaan penyemak imbas akan dikemas kini, mengekalkan jadual pemetaan sedemikian secara manual tidaklah terlalu sukar.
Serupa dengan format surih tindanan. Atribut ini menyimpan timbunan maklumat pengecualian dalam bentuk teks biasa Memandangkan format teks yang digunakan oleh setiap penyemak imbas adalah berbeza, ia juga perlu mengekalkan ungkapan biasa secara manual untuk mengekstrak fungsi setiap bingkai daripada teks biasa (. pengecam), fail (skrip), nombor baris (baris) dan nombor lajur (lajur).
Sekatan keselamatan
Jika anda juga mengalami ralat dengan mesej 'Skrip ralat.', anda akan memahami perkara yang saya maksudkan Ini sebenarnya adalah had penyemak imbas untuk fail skrip dari asal yang berbeza. Sebab untuk sekatan keselamatan ini adalah ini: dengan mengandaikan bahawa HTML yang dikembalikan oleh bank dalam talian selepas pengguna log masuk adalah berbeza daripada HTML yang dilihat oleh pengguna tanpa nama, tapak web pihak ketiga boleh meletakkan URI bank dalam talian ke dalam skrip. atribut src. Sudah tentu, HTML tidak boleh dihuraikan sebagai JS, jadi penyemak imbas akan membuang pengecualian, dan tapak web pihak ketiga boleh menentukan sama ada pengguna dilog masuk dengan menghuraikan lokasi pengecualian. Atas sebab ini, penyemak imbas menapis semua pengecualian yang dilemparkan oleh fail skrip daripada sumber yang berbeza sehingga hanya satu mesej yang tidak berubah seperti 'Ralat skrip yang tinggal, dan semua atribut lain hilang.
Untuk tapak web dalam skala tertentu, adalah perkara biasa untuk fail skrip diletakkan pada CDN dengan sumber yang berbeza. Sekarang walaupun anda membina tapak web kecil anda sendiri, rangka kerja biasa seperti jQuery dan Backbone boleh merujuk terus versi pada CDN awam untuk mempercepatkan muat turun pengguna. Jadi sekatan keselamatan ini menyebabkan beberapa masalah, menyebabkan maklumat pengecualian yang kami kumpulkan daripada Chrome dan Firefox menjadi 'Ralat Skrip' yang sia-sia.
CORS
Untuk memintas sekatan ini, cuma pastikan fail skrip dan halaman itu sendiri mempunyai asal yang sama. Tetapi meletakkan fail skrip pada pelayan yang tidak dipercepatkan oleh CDN tidak akan memperlahankan kelajuan muat turun pengguna? Satu penyelesaian ialah dengan terus meletakkan fail skrip pada CDN, gunakan XMLHttpRequest untuk memuat turun semula kandungan melalui CORS, dan kemudian buat teg
Ini kelihatan mudah, tetapi terdapat banyak butiran untuk dilaksanakan. Mari kita gunakan contoh mudah:
Jika kami sudah mempunyai set alat untuk menjana teg
Seterusnya kita perlu melaksanakan mekanisme lengkap untuk memastikan kandungan fail yang dimuat turun oleh scheduleRemoteScript berdasarkan alamat dan kod yang diperoleh secara langsung oleh scheduleInlineScript boleh dilaksanakan satu demi satu dalam susunan yang betul. Saya tidak akan memberikan kod terperinci di sini Jika anda berminat, anda boleh melaksanakannya sendiri.
Semakan nombor baris terbalik
Mendapatkan kandungan melalui CORS dan kemudian menyuntik kod ke dalam halaman boleh menembusi sekatan keselamatan, tetapi ia akan memperkenalkan masalah baharu, iaitu konflik nombor baris. Pada asalnya, error.script boleh digunakan untuk mencari fail skrip unik dan error.line boleh digunakan untuk mencari nombor baris unik. Sekarang, kerana kesemuanya adalah kod yang dibenamkan dalam halaman, berbilang
Untuk mengelakkan konflik nombor baris, kita boleh membazirkan beberapa nombor baris supaya julat nombor baris yang digunakan oleh kod sebenar dalam setiap teg