ÐÑаÑÐ·ÐµÑ Ð´Ð¾Ð·Ð²Ð¾Ð»ÑÑ Ð½Ð°Ð¼ вÑдÑÑежÑваÑи заванÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð·Ð¾Ð²Ð½ÑÑнÑÑ ÑеÑÑÑÑÑв â ÑкÑипÑÑв, ÑÑеймÑв, зобÑÐ°Ð¶ÐµÐ½Ñ ÑоÑо.
ÐÐ»Ñ ÑÑого пеÑедбаÑено Ð´Ð²Ñ Ð¿Ð¾Ð´ÑÑ:
onloadâ ÑÑпÑÑне заванÑаженнÑ,onerrorâ виÑвлено помилкÑ.
ÐаванÑÐ°Ð¶ÐµÐ½Ð½Ñ ÑкÑипÑа
СкажÑмо, нам поÑÑÑбно заванÑажиÑи ÑÑоÑоннÑй ÑкÑÐ¸Ð¿Ñ Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñи ÑÑнкÑÑÑ, Ñка Ñам Ð·Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑÑ.
Ðи можемо заванÑажиÑи його динамÑÑно, напÑиклад:
let script = document.createElement('script');
script.src = "my.js";
document.head.append(script);
â¦Ðле Ñк запÑÑÑиÑи ÑÑнкÑÑÑ, оголоÑÐµÐ½Ñ Ð²ÑеÑÐµÐ´Ð¸Ð½Ñ ÑÑого ÑкÑипÑа? Ðам поÑÑÑбно поÑекаÑи, поки ÑкÑÐ¸Ð¿Ñ Ð·Ð°Ð²Ð°Ð½ÑажиÑÑÑÑ, Ñ ÑÑлÑки ÑÐ¾Ð´Ñ Ð¼Ð¸ зможемо ÑÑ Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñи.
ÐÐ»Ñ Ð½Ð°ÑÐ¸Ñ Ð²Ð»Ð°ÑÐ½Ð¸Ñ ÑкÑипÑÑв ми могли б викоÑиÑÑовÑваÑи модÑÐ»Ñ JavaScript, але вони не набÑли ÑиÑокого поÑиÑÐµÐ½Ð½Ñ Ñ ÑÑоÑоннÑÑ Ð±ÑблÑоÑÐµÐºÐ°Ñ .
script.onload
ÐÑновним помÑÑником Ñ Ð¿Ð¾Ð´ÑÑ load. Ðона запÑÑкаÑÑÑÑÑ Ð¿ÑÑÐ»Ñ Ð·Ð°Ð²Ð°Ð½ÑÐ°Ð¶ÐµÐ½Ð½Ñ Ñа Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ ÑкÑипÑа.
ÐапÑиклад:
let script = document.createElement('script');
// можемо заванÑажÑваÑи бÑдÑ-Ñкий ÑкÑÐ¸Ð¿Ñ Ð· бÑдÑ-Ñкого доменÑ
script.src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.js"
document.head.append(script);
script.onload = function() {
// ÑкÑÐ¸Ð¿Ñ ÑÑвоÑÑÑ Ð·Ð¼ÑÐ½Ð½Ñ "_"
alert( _.VERSION ); // показÑÑ Ð²ÐµÑÑÑÑ Ð±ÑблÑоÑеки
};
Тож Ñ onload ми можемо викоÑиÑÑовÑваÑи змÑÐ½Ð½Ñ ÑкÑипÑа, виконÑваÑи ÑÑнкÑÑÑ ÑоÑо.
â¦Ð ÑкÑо не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½ÑажиÑи? ÐапÑиклад, Ñакого ÑÑенаÑÑÑ Ð½ÐµÐ¼Ð°Ñ (помилка 404) або ÑеÑÐ²ÐµÑ Ð½Ðµ пÑаÑÑÑ (недоÑÑÑпний).
script.onerror
Ðомилки, ÑÐºÑ Ð²Ð¸Ð½Ð¸ÐºÐ°ÑÑÑ Ð¿Ñд ÑÐ°Ñ Ð·Ð°Ð²Ð°Ð½ÑÐ°Ð¶ÐµÐ½Ð½Ñ ÑкÑипÑа, можна вÑдÑÑежиÑи за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð¿Ð¾Ð´ÑÑ error.
ÐапÑиклад, давайÑе запÑоÑимо ÑкÑипÑ, Ñкого не ÑÑнÑÑ:
let script = document.createElement('script');
script.src = "https://example.com/404.js"; // Ð½ÐµÐ¼Ð°Ñ Ñакого ÑкÑипÑа
document.head.append(script);
script.onerror = function() {
alert("Ðомилка заванÑÐ°Ð¶ÐµÐ½Ð½Ñ " + this.src); // Ðомилка заванÑÐ°Ð¶ÐµÐ½Ð½Ñ https://example.com/404.js
};
ÐвеÑнÑÑÑ ÑвагÑ, Ñо ми не можемо оÑÑимаÑи вÑдомоÑÑÑ Ð¿Ñо Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ HTTP ÑÑÑ. Ðи не знаÑмо, Ñи бÑла Ñе помилка 404 Ñи 500 Ñи ÑоÑÑ ÑнÑе. ÐÑоÑÑо не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½ÑажиÑи.
ÐодÑÑ onload/onerror вÑдÑÑежÑÑÑÑ Ð»Ð¸Ñе Ñаме заванÑаженнÑ.
Ðомилки, ÑÐºÑ Ð¼Ð¾Ð¶ÑÑÑ Ð²Ð¸Ð½Ð¸ÐºÐ½ÑÑи пÑд ÑÐ°Ñ Ð¾Ð±Ñобки Ñа Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ ÑкÑипÑа, виÑ
одÑÑÑ Ð·Ð° Ñамки ÑиÑ
подÑй. ТобÑо: ÑкÑо ÑкÑÐ¸Ð¿Ñ Ð·Ð°Ð²Ð°Ð½ÑажÑÑÑÑÑÑ ÑÑпÑÑно, Ñо запÑÑкаÑÑÑÑÑ onload, навÑÑÑ ÑкÑо в нÑÐ¾Ð¼Ñ Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ пÑогÑамÑваннÑ. Щоб вÑдÑÑежÑваÑи помилки ÑкÑипÑа, можна викоÑиÑÑовÑваÑи глобалÑний обÑобник window.onerror.
ÐнÑÑ ÑеÑÑÑÑи
ÐодÑÑ load Ñа error Ñакож пÑаÑÑÑÑÑ Ð´Ð»Ñ ÑнÑиÑ
ÑеÑÑÑÑÑв, в оÑÐ½Ð¾Ð²Ð½Ð¾Ð¼Ñ Ð´Ð»Ñ Ð±ÑдÑ-Ñкого ÑеÑÑÑÑÑ, Ñкий Ð¼Ð°Ñ Ð·Ð¾Ð²Ð½ÑÑнÑй src.
ÐапÑиклад:
let img = document.createElement('img');
img.src = "https://js.cx/clipart/train.gif"; // (*)
img.onload = function() {
alert(`ÐобÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð·Ð°Ð²Ð°Ð½Ñажено, ÑозмÑÑ ${img.width}x${img.height}`);
};
img.onerror = function() {
alert("ÐÑд ÑÐ°Ñ Ð·Ð°Ð²Ð°Ð½ÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð·Ð¾Ð±ÑÐ°Ð¶ÐµÐ½Ð½Ñ ÑÑалаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°");
};
ХоÑа Ñ Ð´ÐµÑÐºÑ Ð¿ÑимÑÑки:
- ÐÑлÑÑÑÑÑÑ ÑеÑÑÑÑÑв поÑинаÑÑÑ Ð·Ð°Ð²Ð°Ð½ÑажÑваÑиÑÑ, коли вони додаÑÑÑÑÑ Ð´Ð¾ докÑменÑа. Ðле
<img>Ñ Ð²Ð¸Ð½ÑÑком. ÐÑн поÑÐ¸Ð½Ð°Ñ Ð·Ð°Ð²Ð°Ð½ÑажÑваÑиÑÑ, коли оÑÑимÑÑ src(*). - ÐлÑ
<iframe>подÑÑiframe.onloadзапÑÑкаÑÑÑÑÑ Ð¿ÑÑÐ»Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð½Ñ Ð·Ð°Ð²Ð°Ð½ÑÐ°Ð¶ÐµÐ½Ð½Ñ iframe, Ñк Ð´Ð»Ñ ÑÑпÑÑного заванÑаженнÑ, Ñак Ñ Ð² ÑÐ°Ð·Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸.
Це обÑмовлено ÑÑÑоÑиÑними пÑиÑинами.
ÐолÑÑика кÑоÑÐ´Ð¾Ð¼ÐµÐ½Ð½Ð¸Ñ Ð·Ð°Ð¿Ð¸ÑÑв
ÐÑнÑÑ Ð¿Ñавило: ÑкÑипÑи з одного ÑайÑÑ Ð½Ðµ можÑÑÑ Ð¾ÑÑимаÑи доÑÑÑп до вмÑÑÑÑ ÑнÑого ÑайÑÑ. ÐÑже, напÑ. ÑкÑÐ¸Ð¿Ñ Ð½Ð° https://facebook.com не може пÑоÑиÑаÑи поÑÑÐ¾Ð²Ñ ÑкÑинÑÐºÑ ÐºÐ¾ÑиÑÑÑваÑа на https://gmail.com.
Ðбо, ÑкÑо бÑÑи бÑлÑÑ ÑоÑним, одне джеÑело (ÑÑÐ¸Ð¿Ð»ÐµÑ Ð´Ð¾Ð¼ÐµÐ½Ñ/поÑÑÑ/пÑоÑоколÑ) не може оÑÑимаÑи доÑÑÑп до вмÑÑÑÑ Ð· ÑнÑого. Ð¢Ð¾Ð¼Ñ Ð½Ð°Ð²ÑÑÑ ÑкÑо Ñ Ð½Ð°Ñ Ñ ÑÑбдомен або пÑоÑÑо ÑнÑий поÑÑ, Ñе ÑÑÐ·Ð½Ñ Ð´Ð¶ÐµÑела без доÑÑÑÐ¿Ñ Ð¾Ð´Ð¸Ð½ до одного.
Це пÑавило Ñакож Ð²Ð¿Ð»Ð¸Ð²Ð°Ñ Ð½Ð° ÑеÑÑÑÑи з ÑнÑÐ¸Ñ Ð´Ð¾Ð¼ÐµÐ½Ñв.
ЯкÑо ми викоÑиÑÑовÑÑмо ÑкÑÐ¸Ð¿Ñ Ð· ÑнÑого доменÑ, Ñ Ð² нÑÐ¾Ð¼Ñ Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°, ми не можемо оÑÑимаÑи вÑдомоÑÑÑ Ð¿Ñо неÑ.
ÐапÑиклад, вÑзÑмемо ÑкÑÐ¸Ð¿Ñ error.js, Ñкий ÑкладаÑÑÑÑÑ Ð· одного (непÑавилÑного) Ð²Ð¸ÐºÐ»Ð¸ÐºÑ ÑÑнкÑÑÑ:
// ð error.js
noSuchFunction();
Ð¢ÐµÐ¿ÐµÑ Ð·Ð°Ð²Ð°Ð½ÑажÑе його з Ñого Ñамого ÑайÑÑ, де вÑн ÑозÑаÑований:
<script>
window.onerror = function(message, url, line, col, errorObj) {
alert(`${message}\n${url}, ${line}:${col}`);
};
</script>
<script src="/article/onload-onerror/crossorigin/error.js"></script>
Ðи можемо побаÑиÑи Ñ Ð¾ÑоÑий звÑÑ Ð¿Ñо помилки, напÑиклад:
Uncaught ReferenceError: noSuchFunction is not defined
https://javascript.info/article/onload-onerror/crossorigin/error.js, 1:1
Ð¢ÐµÐ¿ÐµÑ Ð´Ð°Ð²Ð°Ð¹Ñе заванÑажимо Ñой Ñамий ÑкÑÐ¸Ð¿Ñ Ð· ÑнÑого доменÑ:
<script>
window.onerror = function(message, url, line, col, errorObj) {
alert(`${message}\n${url}, ${line}:${col}`);
};
</script>
<script src="https://cors.javascript.info/article/onload-onerror/crossorigin/error.js"></script>
ÐвÑÑ Ð²ÑдÑÑзнÑÑÑÑÑÑ, напÑиклад:
Script error.
, 0:0
ÐеÑÐ°Ð»Ñ Ð¼Ð¾Ð¶ÑÑÑ Ð²ÑдÑÑзнÑÑиÑÑ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾ вÑд бÑаÑзеÑа, але ÑÐ´ÐµÑ Ð¾Ð´Ð½Ð°: бÑдÑ-Ñка ÑнÑоÑмаÑÑÑ Ð¿Ñо внÑÑÑÑÑÐ½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи ÑкÑипÑа, вклÑÑаÑÑи ÑÑаÑÑÐ²Ð°Ð½Ð½Ñ ÑÑÐµÐºÑ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº, пÑÐ¸Ñ Ð¾Ð²Ð°Ð½Ð°. Саме ÑомÑ, Ñо вÑн з ÑнÑого доменÑ.
ÐавÑÑо нам поÑÑÑÐ±Ð½Ñ Ð²ÑдомоÑÑÑ Ð¿Ñо помилкÑ?
ÐÑнÑÑ Ð±Ð°Ð³Ð°Ñо ÑеÑвÑÑÑв (Ñ Ð¼Ð¸ можемо ÑÑвоÑиÑи влаÑнÑ), ÑÐºÑ Ð¿ÑоÑлÑÑ
овÑÑÑÑ Ð³Ð»Ð¾Ð±Ð°Ð»ÑÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ window.onerror, збеÑÑгаÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ Ñа надаÑÑÑ ÑнÑеÑÑÐµÐ¹Ñ Ð´Ð»Ñ Ð´Ð¾ÑÑÑÐ¿Ñ Ñа аналÑÐ·Ñ Ð´Ð¾ ниÑ
. Це ÑÑдово, оÑкÑлÑки ми баÑимо ÑеалÑÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸, ÑпÑиÑÐ¸Ð½ÐµÐ½Ñ Ð½Ð°Ñими коÑиÑÑÑваÑами. Ðле ÑкÑо ÑкÑÐ¸Ð¿Ñ Ð¿Ð¾Ñ
одиÑÑ Ð· ÑнÑого джеÑела, Ñо в нÑÐ¾Ð¼Ñ Ð½Ðµ Ñак багаÑо ÑнÑоÑмаÑÑÑ Ð¿Ñо помилки, Ñк ми Ñойно баÑили.
ÐодÑбна полÑÑика кÑоÑÐ´Ð¾Ð¼ÐµÐ½Ð½Ð¸Ñ Ð·Ð°Ð¿Ð¸ÑÑв (CORS) заÑÑоÑовÑÑÑÑÑÑ Ñ Ð´Ð»Ñ ÑнÑÐ¸Ñ ÑипÑв ÑеÑÑÑÑÑв.
Щоб дозволиÑи доÑÑÑп Ñз ÑÑзниÑ
джеÑел, Ñег <script> повинен маÑи аÑÑибÑÑ crossorigin, а Ñакож вÑддалений ÑеÑÐ²ÐµÑ Ð¿Ð¾Ð²Ð¸Ð½ÐµÐ½ надаваÑи ÑпеÑÑалÑÐ½Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¸.
ÐÑнÑÑ ÑÑи ÑÑÐ²Ð½Ñ ÐºÑоÑдоменного доÑÑÑпÑ:
- ÐÐµÐ¼Ð°Ñ Ð°ÑÑибÑÑа
crossoriginâ доÑÑÑп забоÑонено. crossorigin="anonymous"â доÑÑÑп дозволений, ÑкÑо ÑеÑÐ²ÐµÑ Ð²ÑдповÑÐ´Ð°Ñ Ñз заголовкомAccess-Control-Allow-Originз*або наÑим джеÑелом. ÐÑаÑÐ·ÐµÑ Ð½Ðµ надÑÐ¸Ð»Ð°Ñ ÑнÑоÑмаÑÑÑ Ð¿Ñо авÑоÑизаÑÑÑ Ñа Ñайли cookie на вÑддалений ÑеÑвеÑ.crossorigin="use-credentials"â доÑÑÑп дозволений, ÑкÑо ÑеÑÐ²ÐµÑ Ð½Ð°Ð´ÑÐ¸Ð»Ð°Ñ Ð½Ð°Ð·Ð°Ð´ заголовокAccess-Control-Allow-Originз наÑим Ð¿Ð¾Ñ Ð¾Ð´Ð¶ÐµÐ½Ð½Ñм ÑаAccess-Control-Allow-Credentials: true. ÐÑаÑÐ·ÐµÑ Ð½Ð°Ð´ÑÐ¸Ð»Ð°Ñ ÑнÑоÑмаÑÑÑ Ð¿Ñо авÑоÑизаÑÑÑ Ñа Ñайли cookie на вÑддалений ÑеÑвеÑ.
Ðи можеÑе пÑоÑиÑаÑи бÑлÑÑе пÑо доÑÑÑп Ñз ÑÑзниÑ
джеÑел Ñ ÑоздÑÐ»Ñ Fetch: ÐапиÑи мÑж ÑÑзними джеÑелами. ÐÑн опиÑÑÑ Ð¼ÐµÑод fetch Ð´Ð»Ñ Ð¼ÐµÑежевиÑ
запиÑÑв, але полÑÑика ÑоÑно Ñака ж.
Таке понÑÑÑÑ, Ñк âcookiesâ не Ð²Ñ Ð¾Ð´Ð¸ÑÑ Ð´Ð¾ наÑÐ¾Ñ Ð¿Ð¾ÑоÑÐ½Ð¾Ñ Ñеми, але ви можеÑе пÑоÑиÑаÑи пÑо Ð½Ð¸Ñ Ñ ÑоздÑÐ»Ñ Ð¤Ð°Ð¹Ð»Ð¸ cookies, document.cookie.
У наÑÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ Ð¼Ð¸ не мали аÑÑибÑÑа crossorigin. Таким Ñином, кÑоÑдоменний доÑÑÑп бÑв забоÑонений. Ðодаймо його.
Ðи можемо вибиÑаÑи мÑж "anonymous" (Ñайли cookie не надÑилаÑÑÑÑÑ, поÑÑÑбен один заголовок на ÑÑоÑÐ¾Ð½Ñ ÑеÑвеÑа) Ñа "use-credentials" (надÑÐ¸Ð»Ð°Ñ Ñайли cookie, поÑÑÑÐ±Ð½Ñ Ð´Ð²Ð° заголовки на ÑÑоÑÐ¾Ð½Ñ ÑеÑвеÑа).
ЯкÑо нам не Ð²Ð°Ð¶Ð»Ð¸Ð²Ñ Ñайли cookie, Ñо нам пÑдÑйде "anonymous":
<script>
window.onerror = function(message, url, line, col, errorObj) {
alert(`${message}\n${url}, ${line}:${col}`);
};
</script>
<script crossorigin="anonymous" src="https://cors.javascript.info/article/onload-onerror/crossorigin/error.js"></script>
ТепеÑ, ÑкÑо пÑипÑÑÑиÑи, Ñо ÑеÑÐ²ÐµÑ Ð½Ð°Ð´Ð°Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²Ð¾Ðº Access-Control-Allow-Origin, вÑе в поÑÑдкÑ. У Ð½Ð°Ñ Ñ Ð¿Ð¾Ð²Ð½Ð¸Ð¹ звÑÑ Ð¿Ñо помилки.
ÐÑдÑÑмки
ÐобÑÐ°Ð¶ÐµÐ½Ð½Ñ <img>, зовнÑÑÐ½Ñ ÑÑилÑ, ÑкÑипÑи Ñа ÑнÑÑ ÑеÑÑÑÑи забезпеÑÑÑÑÑ Ð¿Ð¾Ð´ÑÑ load Ñа error Ð´Ð»Ñ Ð²ÑдÑÑÐµÐ¶ÐµÐ½Ð½Ñ ÑÑ
заванÑаженнÑ:
loadÑпÑаÑÑовÑÑ Ð¿Ñи ÑÑпÑÑÐ½Ð¾Ð¼Ñ Ð·Ð°Ð²Ð°Ð½ÑаженнÑ,errorÑпÑаÑÑовÑÑ Ð¿Ñи Ð½ÐµÐ²Ð´Ð°Ð»Ð¾Ð¼Ñ Ð·Ð°Ð²Ð°Ð½ÑаженнÑ.
Ðдиним винÑÑком Ñ <iframe>: з ÑÑÑоÑиÑниÑ
пÑиÑин вÑн завжди запÑÑÐºÐ°Ñ load Ð´Ð»Ñ Ð±ÑдÑ-Ñкого завеÑÑÐµÐ½Ð½Ñ Ð·Ð°Ð²Ð°Ð½ÑаженнÑ, навÑÑÑ ÑкÑо ÑÑоÑÑнка не знайдена.
ÐодÑÑ readystatechange Ñакож пÑаÑÑÑ Ð´Ð»Ñ ÑеÑÑÑÑÑв, але викоÑиÑÑовÑÑÑÑÑÑ ÑÑдко, оÑкÑлÑки подÑÑ load/error пÑоÑÑÑÑÑ.
ÐоменÑаÑÑ
<code>, Ð´Ð»Ñ ÐºÑлÑÐºÐ¾Ñ ÑÑдкÑв â обгоÑнÑÑÑ ÑÑ Ñегом<pre>, Ð´Ð»Ñ Ð¿Ð¾Ð½Ð°Ð´ 10 ÑÑдкÑв â викоÑиÑÑовÑйÑе пÑÑоÑниÑÑ (plnkr, jsbin, codepenâ¦)