Как захватить и проанализировать ошибку JavaScript
Все инженеры фронт-энд знают, что JavaScript обладает основными возможностями обработки исключений. Мы можем выбросить новую ошибку (), и браузер также выпустит исключение, когда мы вызовуте ошибку API. Но, по оценкам, большинство фронт-инженеров не рассматривали возможность сбора этой исключительной информации. В любом случае, до тех пор, пока обновление не может воспроизводить после ошибки JavaScript, пользователь может решить проблему, обновляясь, и браузер не будет терпеть неудачу, и все будет хорошо, если этого не произойдет. Это предположение было правдой до того, как приложение для одной страницы стало популярным. Текущее приложение для одной страницы очень сложное после работы в течение некоторого периода времени. Разве вы не полностью переработали предыдущие операции? Таким образом, нам все еще необходимо захватить и проанализировать эту информацию об исключении, а затем мы можем изменить код, чтобы не влиять на пользовательский опыт.
Как поймать исключения
Мы написали сами, бросая новую ошибку (). Тем не менее, исключения, которые возникают при вызове API браузера, не обязательно так легко поймать. Для первого мы также можем поймать его через Try-Catch, для последнего мы должны выслушать глобальные исключения, а затем поймать его.
Попробуйте
Если известно, что некоторые API-интерфейсы браузеров бросают исключения, нам нужно привести к примеру, чтобы избежать всей программы, входящей в нелегальное состояние из-за ошибок. Например, Window.LocalStorage - это такой API.
Кода -копия выглядит следующим образом:
пытаться {
localstorage.setitem ('date', date.now ());
} catch (error) {
ReporterRor (ошибка);
}
Другим распространенным применимым сценарием является обратный сценарий. Поскольку код функции обратного вызова неконтролируемого, мы не знаем, насколько хорош этот код и будут ли называться другие API, которые бросают исключения. Чтобы не привести к выполнению других кодов после вызова обратного вызова из-за ошибок обратного вызова, необходимо вернуть вызов обратно в Try-Catch.
Кода -копия выглядит следующим образом:
слушатели.foreach (function (слушатель) {
пытаться {
слушатель ();
} catch (error) {
ReporterRor (ошибка);
}
});
Window.onerror
Для мест, которые пытается покрыть, не может покрыть, если происходит исключение, его можно захватить только через Window.onerror.
Кода -копия выглядит следующим образом:
window.onerror =
function (errormessage, scripturi, lineNumber) {
ReporterRor ({
Сообщение: Errormessage,
Скрипт: Scripturi,
Линия: белье
});
}
Будьте осторожны, чтобы не быть умным и использовать window.addeventListener или window.attachevent, чтобы прослушать window.onerror. Многие браузеры реализуют только window.onerror или только window. onerror реализация является стандартной. Учитывая, что стандартный черновик также определяет Window.Onerror, нам просто нужно использовать Window.Onerror.
Свойство отсутствует
Предположим, у нас есть функция ReporterRor для сбора пойманных исключений, а затем отправить их партиями на хранилище на стороне сервера для запроса и анализа, какую информацию мы хотим собрать? Более полезная информация включает в себя: Тип ошибки (имя), сообщение об ошибке (сообщение), адрес файла скрипта (Script), номер строки (строка), номер столбца (столбец) и Stack Trace. Если исключение попадает через Try-Catch, вся эта информация находится на объекте ошибки (поддерживается основными браузерами), поэтому ReporterRor также может собирать эту информацию. Но если он захвачен через Window.Onerror, мы все знаем, что эта функция события имеет только 3 параметра, поэтому информация, отличная от этих 3 параметров, потеряна.
Сериализовать сообщения
Если объект ошибки создается нами, то error.message контролируется нами. По сути, то, что мы вкладываем в error.message, и что будет первым параметром (сообщение) window.onerror. (Браузер фактически вносит небольшую модификацию, например, добавление «ошибки непредуденного:». их в Window.Onerror просто выньте его и десериализуйте. Конечно, это ограничивается объектом ошибки, который мы создали сами.
Пятый параметр
Производители браузеров также знают ограничения, которые люди подвергаются при использовании Window.Onerror, поэтому они начинают добавлять новые параметры в Window.Onerror. Учитывая, что только номера строк и никакие номера столбцов кажутся очень симметричными, т.е. сначала добавили номера столбцов и поместили их в четвертый параметр. Тем не менее, все больше обеспокоены тем, могут ли они получить полный стек, поэтому Firefox сказал, что было бы лучше поставить стек в пятый параметр. Но Chrome сказал, что было бы лучше поместить весь объект ошибки в пятый параметр. В результате, поскольку Chrome быстрее, новое окно. Подпись Onerror в Chrome 30, что привело к следующему написанию стандартного проекта.
Кода -копия выглядит следующим образом:
window.onerror = функция (
errormessage,
Scripturi,
бегство,
столбцы,
ошибка
) {
if (ошибка) {
ReporterRor (ошибка);
} еще {
ReporterRor ({
Сообщение: Errormessage,
Скрипт: Scripturi,
Линия: льняное число,
Столбец: ColumnNumber
});
}
}
Регулярность атрибутов
Имена свойств объекта ошибки, которые мы уже обсуждали, основаны на методах именования Chrome. Поэтому нам также нужна специальная функция, чтобы нормализовать объект ошибки, то есть отобразить разные имена атрибутов с единым именем атрибута. Для конкретных практик, пожалуйста, обратитесь к этой статье. Хотя реализация браузера будет обновлена, людям не будет слишком сложно поддерживать такую таблицу отображения.
Аналогичный формат трассировки стека. Это свойство сохраняет информацию о стеке исключения, когда оно происходит в виде простого текста. Имя (идентификатор), файл (скрипт), строка (строка) и столбца (столбец).
Ограничения безопасности
Если вы также столкнулись с ошибкой с сообщением «Ошибка скрипта». Вы поймете, о чем я говорю, что на самом деле является ограничениями браузера для файлов сценариев из разных источников. Причина этого ограничения безопасности заключается в следующем: Предположим, что HTML, возвращенный онлайн-банкиром после входа в систему, отличается от HTML, которого можно увидеть анонимным пользователем, сторонний веб-сайт может поместить URI этого онлайн-банка в сценарий. атрибут SRC. Конечно, HTML не может быть проанализирован как JS, поэтому браузер вызовет исключение, и этот сторонний веб-сайт может определить, вошел ли пользователь, анализируя местоположение исключения. По этой причине браузер фильтровали все исключения, брошенные различными файлами сценариев исходного источника, оставляя только неизменное сообщение, например, «Ошибка скрипта». И все другие атрибуты исчезают.
Для веб -сайтов определенного масштаба это нормально для размещения файлов сценариев на CDN и различных источников. Теперь, даже если вы создаете небольшой веб -сайт самостоятельно, общие фреймворки, такие как JQUERY и BACKBONE, могут напрямую ссылаться на версию на публичном CDN, чтобы ускорить загрузки пользователей. Таким образом, это ограничение безопасности вызывает некоторые проблемы, что приводит к тому, что информация о исключении, которую мы собираем от Chrome и Firefox, быть бесполезной «ошибкой скрипта».
Корр
Если вы хотите обойти это ограничение, просто убедитесь, что файл сценария и сами страница одинаковы. Но разве не размещение файлов сценариев на серверах, которые не ускоряются CDN, уменьшить скорость загрузки пользователя? Одним из решений является продолжение размещения файла скрипта на CDN, используйте Xmlhttprequest, чтобы загрузить контент обратно через Cors, а затем создать тег <croppling> для внедрения его в страницу. Код, встроенный на странице, конечно, является тем же происхождением.
Это просто сказать, но есть много деталей для реализации. Чтобы привести простой пример:
Кода -копия выглядит следующим образом:
<script src = "http://cdn.com/step1.js"> </script>
<Скрипт>
(функция step2 () {}) ();
</script>
<script src = "http://cdn.com/step3.js"> </script>
Мы все знаем, что если в шаге 1, шаге 2 и шаге 3 зависимости он должен выполняться строго в этом порядке, в противном случае может возникнуть ошибка. Браузер может запросить файлы STEP1 и STEP3 параллельно, но заказ гарантирован при выполнении. Если мы получим содержимое файла Step1 и Step3, используя Xmlhttprequest, мы должны обеспечить правильный порядок сами. Кроме того, не забывайте шаг2.
Если у нас уже есть полный набор инструментов для генерации тегов <croppl> для разных страниц на веб -сайте, нам нужно настроить этот набор инструментов для внесения изменений в теги <script>:
Кода -копия выглядит следующим образом:
<Скрипт>
phoneulerEmotescript ('http://cdn.com/step1.js');
</script>
<Скрипт>
ganedicinlinescript (function code () {
(функция step2 () {}) ();
});
</script>
<Скрипт>
phoneulerEmotescript ('http://cdn.com/step3.js');
</script>
Нам необходимо реализовать две функции SchearlereMotescript и DepareInlinescript, и убедиться, что они определены до первого тега <Script>, который ссылается на внешний файл сценария, а затем оставшиеся теги <script> будут переписаны в вышеупомянутую форму. Обратите внимание, что функция STEP2, которая была выполнена немедленно, была помещена в более крупную функцию кода. Функция кода не будет выполнена, это просто контейнер, так что исходный код STEP2 можно сохранить без выхода, но он не будет выполнен немедленно.
Затем нам необходимо реализовать полный механизм, чтобы гарантировать, что содержимое файла, загруженное с помощью ShadulerEmotescript на основе адреса, и кода, непосредственно полученный с помощью PadericInlinescript, может быть выполнен один за другим в правильном порядке. Я не дам подробный код здесь.
Проверка номера строки
Получение контента через COR и инъекционное код на страницу может преодолеть ограничения безопасности, но это введет новую проблему, то есть конфликты номера строк. Первоначально уникальный файл скрипта может быть расположен через error.script, а затем уникальный номер строки может быть расположен через erry.line. Теперь, поскольку все это коды, встроенные на странице, несколько тегов <croppling> нельзя различить по ошибке. ..
Чтобы избежать конфликтов номера строки, мы можем тратить некоторые номера строк, чтобы интервалы номера строки, используемые фактическим кодом в каждом теге <сценарии>, не перекрывались друг с другом. Например, предполагая, что фактический код в каждом теге <script> не превышает 1000 строк, я могу сделать код в первой линии <script> Tag. 10012000 (1000 пустых строк были вставлены перед вставкой), код третьего тега <Script> занимает строку 20013000 (до вставки) и т. Д. Затем мы используем атрибут Data-* для записи этой информации для легкой проверки.
Кода -копия выглядит следующим образом:
<Скрипт
data-src = "http://cdn.com/step1.js"
data-line-start = "1"
>
// код для шага 1
</script>
<script data-line-start = "1001">
// '/n' * 1000
// код для шага 2
</script>
<Скрипт
data-src = "http://cdn.com/step3.js"
data-line-start = "2001"
>
// '/n' * 2000
// код для шага 3
</script>
После этой обработки, если ошибка ошибки. Линия составляет 3005, это означает, что фактической ошибкой .Script должна быть 'http://cdn.com/step3.js', в то время как фактическая ошибка. Линия должна быть 5. Мы можем завершить этот номер строки обратной проверки в функции ReporterRor, упомянутой ранее.
Конечно, поскольку мы не можем гарантировать, что каждый файл сценария имеет только 1000 строк, также возможно, что некоторые файлы скрипта составляют значительно менее 1000 строк, поэтому нет необходимости приспособленно выделять интервал линии 1000 по каждому тегу <Script>. Мы можем выделить интервалы на основе фактического количества линий сценариев, просто убедитесь, что интервалы, используемые каждым тегом <Script>, не перекрываются.
Атрибут кроссоригин
Ограничения безопасности, налагаемые браузерами на содержание из разных источников, конечно, не ограничиваются тегами <Script>. Поскольку xmlhttprequest может прорваться через это ограничение через Cors, почему ресурсы непосредственно ссылаются через теги не разрешены? Это, безусловно, нормально.
Ограничение ссылки на различные файлы скриптов источника для тегов <Script> также применяется к ссылке на различные файлы изображений источника для тегов <img>. Если тег <img> является другим источником, когда используется на рисунке <canvas>, <Canvas> станет состоянием только для записи, гарантируя, что веб-сайт не может украсть несанкционированные данные изображения из разных источников через JavaScript. Позже, тег <img> решил эту проблему, введя атрибут Crossorigin. Если Crossorigin = "Anonymous", это эквивалентно анонимным Cors;
Поскольку тег <img> может сделать это, почему тег <script> не может сделать это? Таким образом, производитель браузеров добавил тот же атрибут кроссоригина в тег <croppl> для решения вышеуказанных ограничений безопасности. Теперь поддержка Chrome и Firefox для этой собственности полностью бесплатная. Safari будет относиться к Crossorigin = "anonymous" как crossorigin = "use-credentials", и результатом является то, что если сервер поддерживает только анонимные Cors, Safari будет рассматривать аутентификацию как сбой. Поскольку сервер CDN предназначен для возврата только статического контента по соображениям производительности, невозможно динамически вернуть заголовок HTTP, необходимый для аутентификации COR на основе запросов.
Суммировать
Обработка исключений JavaScript выглядит просто и ничем не отличается от других языков, но не так легко поймать все исключения и проанализировать свойства. Хотя некоторые сторонние услуги теперь предоставляют услуги Google Analytics, которые затрагивают исключения JavaScript, если вы хотите понять детали и принципы, вы должны сделать это самостоятельно.