Все инженеры фронт-энд знают, что JavaScript обладает основными возможностями обработки исключений. Мы можем выбросить новую ошибку (), и браузер также выпустит исключение, когда мы вызовуте ошибку API. Но подсчитано, что большинство фронт-инженеров никогда не рассматривали информацию об этой информации об исключении
В любом случае, до тех пор, пока обновление не может воспроизводить после ошибки JavaScript, пользователь может решить проблему, обновляясь, и браузер не будет терпеть неудачу, и все будет хорошо, если этого не произойдет. Это предположение было правдой до того, как приложение для одной страницы стало популярным. Текущее приложение для одной страницы чрезвычайно сложное после работы в течение определенного периода времени. Пользователи могли выполнить несколько операций ввода, прежде чем они пришли сюда. Как они могут освежить, если говорят, что хотят? Разве вы не полностью переработали предыдущие операции? Таким образом, нам все еще необходимо захватить и проанализировать эту информацию об исключении, а затем мы можем изменить код, чтобы не влиять на пользовательский опыт.
Как поймать исключения
Мы написали сами бросить новую ошибку (). Если мы хотим захватить, мы, безусловно, можем запечатлеть его, потому что мы очень хорошо знаем, где написан бросок. Однако исключения, которые возникают при вызове API браузера, не обязательно так легко поймать. В некоторых API говорят, что исключения будут выбраны в стандарте, а в некоторых API есть только отдельные браузеры, которые бросают исключения из -за различий в реализации или дефектов. Для первого мы также можем поймать его через Try-Catch, для последнего мы должны выслушать глобальные исключения, а затем поймать его.
Попробуйте
Если известно, что некоторые API-интерфейсы браузеров бросают исключения, нам нужно привести к примеру, чтобы избежать всей программы, входящей в нелегальное состояние из-за ошибок. Например, Window.LocalStorage - это такой API. Исключение будет добавлено после того, как написание данных превышает ограничение емкости, и это также будет верно в режиме частного просмотра Safari.
Кода -копия выглядит следующим образом:
пытаться {
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. Учитывая, что только номера строк и никакие номера столбцов кажутся очень симметричными, т.е. сначала добавили номера столбцов и поместили их в четвертый параметр. Тем не менее, все больше обеспокоены тем, могут ли они получить полный стек, поэтому Firefox сказал, что было бы лучше поставить стек в пятый параметр. Но Chrome сказал, что было бы лучше поставить весь объект ошибки в пятый параметр. Любой атрибут, который вы хотите прочитать, включая пользовательские атрибуты. В результате, поскольку Chrome быстрее, новое окно. Подпись Onerror в Chrome 30, что привело к следующему написанию стандартного проекта.
Кода -копия выглядит следующим образом:
window.onerror = функция (
errormessage,
Scripturi,
бегство,
столбцы,
ошибка
) {
if (ошибка) {
ReporterRor (ошибка);
} еще {
ReporterRor ({
Сообщение: Errormessage,
Скрипт: Scripturi,
Линия: льняное число,
Столбец: ColumnNumber
});
}
}
Регулярность атрибутов
Имена свойств объекта ошибки, которые мы обсуждали ранее, основаны на методах именования хрома. Тем не менее, разные браузеры называют свойства объекта ошибки по -разному. Например, адрес файла скрипта называется Script в Chrome, но имени файла в Firefox. Поэтому нам также нужна специальная функция, чтобы нормализовать объект ошибки, то есть отобразить разные имена атрибутов с единым именем атрибута. Для конкретных практик, пожалуйста, обратитесь к этой статье. Хотя реализация браузера будет обновлена, людям не будет слишком сложно поддерживать такую таблицу отображения.
Аналогичный формат трассировки стека. Это свойство сохраняет информацию о стеке исключения, когда оно происходит в простом тексте. Поскольку текстовые форматы, используемые каждым браузером, различны, также необходимо поддерживать регулярное выражение для извлечения имени функции (идентификатор), файла (скрипт), номера строки (строка) и номера столбца (столбец) каждого кадра из простого текста.
Ограничения безопасности
Если вы также столкнулись с ошибкой с сообщением «Ошибка скрипта». Вы поймете, о чем я говорю, что на самом деле является ограничениями браузера для файлов сценариев из разных источников. Причина этого ограничения безопасности заключается в следующем: Предположим, что HTML, возвращенный онлайн-банкиром после входа в систему, отличается от HTML, который можно увидеть анонимным пользователем, сторонний веб-сайт может поместить URI этого онлайн-банка в атрибут Script.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. Шаг2 может быть выполнен, когда шаг 1 загружен в неблокирующей форме, поэтому мы также должны вмешиваться в Шаг2 и позволить ему ждать, пока шаг 1 завершится перед выполнением.
Если у нас уже есть полный набор инструментов для генерации тегов <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. Теперь, поскольку все коды, встроенные на странице, являются всеми кодами, множественные теги <Script> нельзя различить по ошибке. Тем не менее, номер строки внутри каждого тега <Script> рассчитывается из 1, что приводит к тому, что мы не сможем использовать информацию об исключении для поиска местоположения исходного кода, где находится ошибка.
Чтобы избежать конфликтов с номерами строки, мы можем тратить некоторые номера строк, чтобы интервалы номера строки, используемые фактическим кодом в каждом теге <Script>, не перекрывались друг с другом. Например, предполагая, что фактический код в каждом теге <Script> не превышает 1000 строк, тогда я могу позволить коду в первой строке <cropript> Tag Line 11000, код во второй линии <script> tag occupy 10012000 (1000 пустые строки были вставлены ранее), код в третьей теге <сценариста> Test 20013000 (2000 пустые строки были установлены ранее), и So So So Ol. Затем мы используем атрибут 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; Если Crossorigin = "use-credentials", это эквивалентно сертифицированным CORS.
Поскольку тег <img> может сделать это, почему тег <script> не может сделать это? Таким образом, производитель браузеров добавил тот же атрибут кроссоригина в тег <croppl> для решения вышеуказанных ограничений безопасности. Теперь поддержка Chrome и Firefox для этой собственности полностью бесплатная. Safari будет относиться к Crossorigin = "anonymous" как crossorigin = "use-credentials", и результатом является то, что если сервер поддерживает только анонимные Cors, Safari будет рассматривать аутентификацию как сбой. Поскольку сервер CDN предназначен для возврата только статического контента по соображениям производительности, невозможно динамически вернуть заголовок HTTP, необходимый для аутентификации COR на основе запросов. Safari эквивалентен невозможности использовать эту функцию для решения вышеуказанной проблемы.
Суммировать
Обработка исключений JavaScript выглядит просто и ничем не отличается от других языков, но не так легко поймать все исключения и проанализировать свойства. Теперь, хотя некоторые сторонние услуги предоставляют Google Analytics, которые затрагивают исключения JavaScript, если вы хотите понять детали и принципы, вам все равно нужно сделать это самостоятельно.