Rumah  >  Artikel  >  hujung hadapan web  >  Pengecualian JavaScript mengendalikan kemahiran explanation_javascript terperinci

Pengecualian JavaScript mengendalikan kemahiran explanation_javascript terperinci

WBOY
WBOYasal
2016-05-16 16:15:30903semak imbas

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.

Salin kod Kod adalah seperti berikut:

cuba {
localStorage.setItem('date', Date.now());
} tangkap (ralat) {
reportError(error);
}


Satu lagi kes penggunaan biasa untuk try-catch ialah panggilan balik. Oleh kerana kod fungsi panggil balik di luar kawalan kami, kami tidak tahu tentang kualiti kod atau sama ada API lain yang akan mengeluarkan pengecualian akan dipanggil. Untuk mengelakkan kod lain selepas memanggil balik daripada tidak dapat dilaksanakan kerana ralat panggil balik, panggilan balik perlu dimasukkan ke dalam try-catch.

Salin kod Kod adalah seperti berikut:

listeners.forEach(function(pendengar) {
cuba {
pendengar();
} tangkap (ralat) {
reportError(error);
}
});


tetingkap.onerror

Untuk kawasan yang tidak diliputi oleh try-catch, jika pengecualian berlaku, ia hanya boleh ditangkap melalui window.onerror.

Salin kod Kod adalah seperti berikut:

window.onerror =
function(errorMessage, scriptURI, lineNumber) {
reportError({
mesej: errorMessage,
skrip: scriptURI,
baris: lineNumber
});
}


Berhati-hati untuk tidak menjadi pandai dan gunakan window.addEventListener atau window.attachEvent untuk mendengar window.onerror. Banyak pelayar hanya melaksanakan window.onerror, atau hanya pelaksanaan window.onerror adalah standard. Memandangkan draf standard juga mentakrifkan window.onerror, kita hanya boleh menggunakan 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.

Salin kod Kod adalah seperti berikut:

window.onerror = function(
mesej ralat,
scriptURI,
Nombor baris,
Nombor lajur,
ralat
) {
jika (ralat) {
reportError(error);
} lain {
reportError({
mesej: errorMessage,
skrip: scriptURI,
baris: lineNumber,
lajur: lajurNombor
});
}
}


Penyaturan atribut

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 Kod yang dibenamkan dalam halaman sudah tentu dari sumber yang sama.

Ini kelihatan mudah, tetapi terdapat banyak butiran untuk dilaksanakan. Mari kita gunakan contoh mudah:

Salin kod Kod adalah seperti berikut: