이틀 전 2048게임 이용자가 게임을 실행한 후 게임을 할 수 없다고 신고했습니다. 게임 패널이 1개뿐이고, 숫자 초기화도 안 되고, 이동도 안 되는 기기였습니다. 그리고 iOS 5.1. WeChat에서 Safari를 열려고 했지만 여전히 작동하지 않습니다. 해당 게임은 HTML5 기능을 많이 사용하고 있어 JS 오류로 인해 발생하는 것으로 대략 추정됩니다. 그런데 그러한 정보를 어떻게 포착할 수 있을까요? 물론 전설적인 window.onerror 입니다.
W3C에서 window.onerror에 대한 메서드 본문 소개 찾기:
이는 기본적으로 window.onerror 메소드의 경우 다음과 같이 작성할 수 있음을 의미합니다.
/** * @param {String} errorMessage 错误信息 * @param {String} scriptURI 出错的文件 * @param {Long} lineNumber 出错代码的行号 * @param {Long} columnNumber 出错代码的列号 * @param {Object} errorObj 错误的详细信息,Anything */ window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) { // TODO }
그러나 사용 중 호환성 문제에 주의해야 합니다. 모든 브라우저에 매개변수 목록의 모든 매개변수가 있는 것은 아닙니다. Chrome 등은 초안 브라우저 표준의 선두주자이므로 이 매개변수만 사용하세요!
그러므로 간단한 데모를 작성하여 사용해 볼 수 있습니다.
<!DOCTYPE html> <html> <head> <title>Js错误捕获</title> <script type="text/javascript"> /** * @param {String} errorMessage 错误信息 * @param {String} scriptURI 出错的文件 * @param {Long} lineNumber 出错代码的行号 * @param {Long} columnNumber 出错代码的列号 * @param {Object} errorObj 错误的详细信息,Anything */ window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) { console.log("错误信息:" , errorMessage); console.log("出错文件:" , scriptURI); console.log("出错行号:" , lineNumber); console.log("出错列号:" , columnNumber); console.log("错误详情:" , errorObj); } </script> </head> <body> <script type="text/javascript" src="error.js"></script> </body> </html>
error.js 파일의 내용을 보려면 다음과 같이 작성하세요.
throw new Error("오류가 발생했습니다!")
브라우저를 실행한 후 콘솔을 열면 기본적으로 다음과 같습니다.
따라서 이러한 데이터를 보고할 수 있습니다.
물론 위의 error.js는 html 페이지와 동일한 도메인 이름에 속합니다. error.js가 동일한 도메인에 속하지 않으면 어떻게 될까요? error.js에 대한 참조를 변경해 보겠습니다.
콘솔을 다시 열면 다음과 같은 내용이 표시됩니다.
오류 메시지 하나만 캡처하는 window.onerror 메서드와 동일하며 참조 값이 없는 고정 문자열입니다. 몇 가지 정보(Webkit 소스 코드)를 확인한 결과, 브라우저가 스크립트 리소스 로딩을 구현하는 경우 원본이 아닌 리소스인 경우 동일한 원본 정책으로 판단되는 것을 발견했습니다. 스크립트 오류”:
다행히도 script 태그에는 crossorigin 속성이 있습니다. 이를 설정하면 더 자세한 오류 정보를 표시할 수 있습니다.
페이지를 새로 고치면 콘솔에 다음과 같이 출력되는 것을 볼 수 있습니다.
이 오류가 발생하는 것은 놀라운 일이 아닙니다. error.js가 crossorigin으로 설정되어 있으므로 error.js의 HTTP 응답 헤더도 원본이 아닌 소스에서 액세스할 수 있도록 설정되어야 합니다. 헤더 설정을 용이하게 하려면 error.js를 약간 변경하고 이름을 error-js.php로 바꾸세요.
<?php header('Access-Control-Allow-Origin:*'); header('Content-type:text/javascript'); ?> throw new Error('出错了');
자, 기술적 세부 분석이 끝났습니다! 내 2048 게임 정적 리소스는 정적 도메인(동일하지 않은 소스)에 배치되므로 window.onerror를 통해 오류 정보를 캡처하려면 위의 마지막 상황에 따라 작동해야 합니다.
1. 스크립트의 crossorigin 속성을 추가합니다
2. 서버를 구성하고 정적 리소스 Javascript의 응답을 Access-Control-Allow-Origin으로 설정합니다