또 다른 일반적인 try-catch 적용 시나리오는 콜백입니다. . 콜백 함수의 코드는 우리가 통제할 수 없기 때문에 코드의 품질이나 예외를 발생시키는 다른 API가 호출되는지 여부에 대해 알 수 없습니다. 콜백을 호출한 후 다른 코드가 콜백 오류로 인해 실행되지 않는 것을 방지하려면 콜백을 try-catch에 다시 넣어야 합니다.
reportError({
message: errorMessage,
script: scriptURI,
line: lineNumber
})
}
창문을 사용하지 않도록 주의하고 window.addEventListener 또는 window.attachEvent를 사용하여 window.onerror를 수신하세요. 많은 브라우저에서는 window.onerror만 구현하거나 window.onerror 구현만 표준입니다. 표준 초안에서도 window.onerror를 정의하고 있다는 점을 고려하면 그냥 window.onerror를 사용해도 됩니다.
속성 손실
캡처된 예외를 수집한 다음 쿼리 및 분석을 위해 일괄적으로 서버측 저장소로 보내는 reportError 함수가 있다고 가정해 보겠습니다. 그렇다면 우리가 수집하려는 정보는 무엇입니까? 더 유용한 정보에는 오류 유형(이름), 오류 메시지(메시지), 스크립트 파일 주소(script), 줄 번호(line), 열 번호(column) 및 스택 추적(stack)이 포함됩니다. try-catch를 통해 예외가 포착되면 이 정보는 Error 개체(주요 브라우저에서 지원됨)에 있으므로 reportError도 이 정보를 수집할 수 있습니다. 하지만 window.onerror를 통해 캡처하면 이 이벤트 함수에는 3개의 매개변수만 있으므로 이 3개 매개변수 이외의 정보는 손실된다는 것을 우리 모두 알고 있습니다.
직렬화된 메시지
Error 객체가 스스로 생성된 경우 error.message는 우리가 제어합니다. 기본적으로 우리가 error.message에 무엇을 입력하든 window.onerror의 첫 번째 매개변수(메시지)가 됩니다. (브라우저는 실제로 'Uncaught Error:' 접두사를 추가하는 등 약간의 수정을 합니다.) 따라서 우리가 관심 있는 속성(예: JSON.Stringify)을 직렬화하고 이를 error.message에 저장한 다음 읽을 수 있습니다. window.onerror에서 꺼내서 역직렬화하세요. 물론 이는 우리가 직접 생성한 Error 개체로 제한됩니다.
다섯 번째 매개변수
브라우저 제조사들도 window.onerror를 사용할 때 모든 사람이 직면하는 한계를 알고 있었기 때문에 window.onerror에 새로운 매개변수를 추가하기 시작했습니다. 행 번호만 있고 열 번호가 없는 것을 고려하여 IE는 먼저 열 번호를 추가하고 이를 네 번째 매개 변수에 넣습니다. 그러나 모든 사람들은 완전한 스택을 얻을 수 있는지에 대해 더 관심을 갖고 있으므로 Firefox는 스택을 다섯 번째 매개 변수에 넣는 것이 더 나을 것이라고 말했습니다. 하지만 Chrome에서는 전체 Error 개체를 다섯 번째 매개변수에 넣는 것이 더 낫다고 말했습니다. 맞춤 속성을 포함하여 원하는 모든 속성을 읽을 수 있습니다. 결과적으로 Chrome은 더 빠르게 움직이고 Chrome 30에서 새로운 window.onerror 서명을 구현하여 이에 따라 표준 초안이 작성되었습니다.
window.onerror = function(
errorMessage,
scriptURI,
lineNumber,
columnNumber,
error
) {
if (오류) {
reportError(오류)
} else {
reportError( {
메시지: errorMessage,
script: scriptURI,
line: lineNumber,
column: columnNumber
})
속성 정규화
이전에 논의한 Error 개체 속성의 이름은 Chrome 명명 방법을 기반으로 합니다. 그러나 Chrome에서는 스크립트 파일 주소와 같이 브라우저마다 다른 방식으로 Error 개체 속성의 이름을 지정합니다. 스크립트라고 부르지만 Firefox에서는 파일 이름이라고 합니다. 따라서 Error 객체를 정규화하는, 즉 서로 다른 속성 이름을 통합된 속성 이름에 매핑하는 특수 함수도 필요합니다. 구체적인 방법은 이 글을 참고하세요. 브라우저 구현이 업데이트되더라도 이러한 매핑 테이블을 수동으로 유지 관리하는 것은 그리 어렵지 않습니다.
스택 추적 형식과 유사합니다. 이 속성은 예외 정보 스택을 일반 텍스트 형식으로 저장합니다. 각 브라우저에서 사용하는 텍스트 형식이 다르기 때문에 일반 텍스트에서 각 프레임의 기능을 추출하려면 정규식을 수동으로 유지해야 합니다. 식별자), 파일(스크립트), 줄 번호(line) 및 열 번호(열)입니다.
보안 제한
'스크립트 오류' 메시지와 함께 오류가 발생했다면 실제로는 다른 원본 스크립트 파일에 대한 브라우저의 응답을 이해하게 될 것입니다. 이러한 보안 제한의 이유는 사용자가 로그인한 후 온라인 은행에서 반환한 HTML이 익명 사용자가 본 HTML과 다르다고 가정하면 제3자 웹사이트에서 온라인 은행의 URI를 스크립트에 넣을 수 있기 때문입니다. src 속성. 물론 HTML은 JS로 구문 분석할 수 없으므로 브라우저에서는 예외가 발생하며, 타사 웹사이트에서는 예외 위치를 구문 분석하여 사용자가 로그인했는지 여부를 확인할 수 있습니다. 이러한 이유로 브라우저는 '스크립트 오류'와 같은 변경되지 않은 메시지가 하나만 남고 다른 모든 속성이 사라질 때까지 다양한 소스의 스크립트 파일에서 발생하는 모든 예외를 필터링합니다.
특정 규모의 웹사이트에서는 스크립트 파일이 다양한 소스의 CDN에 배치되는 것이 일반적입니다. 이제 자신만의 작은 웹사이트를 구축하더라도 jQuery 및 Backbone과 같은 일반적인 프레임워크는 공개 CDN의 버전을 직접 참조하여 사용자 다운로드 속도를 높일 수 있습니다. 따라서 이러한 보안 제한은 일부 문제를 야기하여 Chrome 및 Firefox에서 수집한 예외 정보가 쓸모없는 '스크립트 오류'가 되도록 만듭니다.
CORS
이 제한을 우회하려면 스크립트 파일과 페이지 자체의 출처가 동일한지 확인하세요. 그런데 CDN으로 가속되지 않는 서버에 스크립트 파일을 놓으면 사용자의 다운로드 속도가 느려지지 않나요? 한 가지 해결 방법은 계속해서 CDN에 스크립트 파일을 배치하고 XMLHttpRequest를 사용하여 CORS를 통해 콘텐츠를 다시 다운로드한 다음 <script> 태그를 만들어 페이지에 삽입하는 것입니다. 페이지에 포함된 코드는 물론 동일한 소스에서 가져온 것입니다. <br><br>간단해 보이지만 구현해야 할 세부 사항이 많습니다. 간단한 예를 들어보겠습니다. <br><div class="codetitle">
<span><a style="CURSOR: pointer" data="8772" class="copybut" id="copybut8772" onclick="doCopy('code8772')"><u>코드 복사 </u></a></span> 코드는 다음과 같습니다. </div>
<div class="codebody" id="code8772"> <br><script src ="http://cdn.com/step1.js"></script>
<script> <br>(function step2() {})(); ; <br><script src="http://cdn.com/step3.js"></script>
우리 모두는 1단계, 2단계, 3단계가 있다면 알고 있습니다. 종속성 그렇다면 이 순서를 엄격히 따라야 합니다. 그렇지 않으면 오류가 발생할 수 있습니다. 브라우저는 step1과 step3의 파일을 병렬로 요청할 수 있지만 실행 중에는 순서가 보장됩니다. XMLHttpRequest를 통해 step1과 step3의 파일 내용을 직접 얻는 경우 순서가 올바른지 확인해야 합니다. 또한 step2는 step1이 비차단 방식으로 다운로드될 때 실행될 수 있으므로 step1을 실행하기 전에 step1이 완료될 때까지 기다리도록 수동으로 개입해야 합니다.
웹사이트의 여러 페이지에 대해 <script> 태그를 생성하는 도구 세트가 이미 있는 경우 이 도구 세트를 조정하여 <script> 태그를 변경해야 합니다. <br> <br><div class="codetitle"><span><a style="CURSOR: pointer" data="91019" class="copybut" id="copybut91019" onclick="doCopy('code91019')">코드 복사<u></u></a> 코드는 다음과 같습니다.</span></div> <div class="codebody" id="code91019"><script> //cdn.com/step1.js'); <br><script> <br>scheduleInlineScript(function code() { <br>(function step2() {})() ; <br> }) <br></script>
<script>scheduleRemoteScript('http://cdn.com/step3.js'); <br><br><br>다음으로 주소를 기반으로 ScheduleRemoteScript로 다운로드한 파일 콘텐츠와 ScheduleInlineScript로 직접 얻은 코드가 올바른 순서로 차례로 실행될 수 있도록 완전한 메커니즘을 구현해야 합니다. 여기서는 자세한 코드를 제공하지 않겠습니다. 관심이 있으시면 직접 구현해 보세요. <br>줄 번호 역 확인 <br><br>CORS를 통해 콘텐츠를 가져온 다음 페이지에 코드를 삽입하면 보안 제한을 뚫을 수 있지만 새로운 문제, 즉 줄 번호 충돌이 발생합니다. 원래는 error.script를 사용하여 고유한 스크립트 파일을 찾을 수 있었고 error.line을 사용하여 고유한 줄 번호를 찾을 수 있었습니다. 이제 페이지에 포함된 코드이므로 여러 개의 <script> 태그를 error.script로 구분할 수 없습니다. 그러나 각 <script> 태그 안의 줄 번호는 1부터 시작합니다. 오류가 있는 소스 코드 위치를 찾는 데 사용됩니다. <br><br>줄 번호 충돌을 피하기 위해 각 <script> 태그의 실제 코드에서 사용하는 줄 번호 범위가 서로 겹치지 않도록 일부 줄 번호를 낭비할 수 있습니다. 예를 들어, 각 <script> 태그의 실제 코드가 1000줄을 넘지 않는다고 가정하면 첫 번째 <script> 태그의 코드는 1~1000줄을 차지하고 두 번째 코드는 <script> 태그는 1001~2000행(그 앞에 1000개의 빈 행 삽입)을 차지하고 세 번째 <script> 태그의 코드는 2001~3000행(그 앞에 2000개의 빈 행을 삽입)을 차지합니다. 그런 다음 data-* 속성을 사용하여 쉽게 검색할 수 있도록 이 정보를 기록합니다. <br><br><div class="codetitle"><span><a style="CURSOR: pointer" data="17722" class="copybut" id="copybut17722" onclick="doCopy('code17722')">코드 복사<u></u></a> 코드는 다음과 같습니다.</span></div> <div class="codebody" id="code17722"><script <BR>data-src ="http ://cdn.com/step1.js" <BR>data-line-start="1" <BR>> <br>// 1단계 코드 <br></script> >< script data-line-start="1001">
// 'n' * 1000
// 2단계 코드
이러한 처리 후 오류의 error.line이 3005이면 실제 error.script는 'http://cdn.com/step3.js'여야 하고 실제 error.line은 3005라는 뜻입니다. 5이어야 합니다. 앞서 언급한 reportError 함수에서 이 줄 번호 역방향 검사를 완료할 수 있습니다.
물론 각 스크립트 파일에 1000줄만 있다고 보장할 수 없고 일부 스크립트 파일은 1000줄보다 훨씬 작을 수 있으므로 각 < 스크립트> 각