📜  在 JavaScript 中记录脚本错误

📅  最后修改于: 2021-11-07 07:54:35             🧑  作者: Mango

在本文中,我们将学习使用 JavaScript 记录脚本错误。如果来自任何其他源的脚本在网站下运行/执行(例如在 iframe 中)或任何查看器使用浏览器控制台尝试更改脚本或您想监视 JS 代码的情况下,它很有用投入生产时可能会出现错误。

方法:我们将学习 3 种方法来完成此任务——所有方法都遵循相同的方法,但实现方法和提取有用信息的方式不同。使用最适合您的情况。

  1. window.addEventListener(“error”, //yourErrorLoggerFunction ) — 将错误事件附加到窗口对象 (DOM)。
  2. document.querySelector(‘body’).onerror= //yourErrorLoggerFunction — body 标记中的错误侦听器 -> 在同源或同源跨脚本中均有效。
  3. 创建一个脚本元素并将其附加到源的正文标记。

所有这三种方法都可以在同一源或任何外部源中实现。

注意— 确保这是浏览器执行的第一件事(如果您不确定,强烈建议使用方法 2)。

方法一:在这个方法中,我们将一个事件监听器附加到我们的窗口对象上。每当发生任何脚本错误时,都会触发附加的 errorLogger函数,在 errorLoggerFunction 中,我们将从 errorLogger函数接收的事件对象中提取所有有用的信息。

Javascript
window.addEventListener("error", errorLog);
 
function errorLog(event) {
 
    // Declare all variables as null
    // necessary in case of multiple
    // errors to be logged
    let msg = source = lineno = colno
                    = error = time = "";
 
    // Use prevent deafult in case you
    // don't want the error to be logged
    // in the console / hide the error
    event.preventDefault();
    msg = event.message;
    source = event.filename;
    lineno = event.lineno;
    colno = event.colno;
    error = event.error;
    time = event.time;
    // This time is in ms and tells us
    // time after which the error occured
    // after the page was loaded
    // a lot other information can be
    // gathered - explore the event object
    // After extracting all the information
    // from this object now log it on your
    // server Database
}


HTML


 

    
    
    Document

 

    

        No Errors     

                  


Javascript
const bodyTag =
 
    // body tag of External HTML
    // Markup or of your page
    bodyTag.onerror = errorLogger;
 
function errorLogger(msg, url,
    lineNo, columnNo, error) {
 
    // Now process your Error
    // Information as you desire
}


HTML


 

    
    

 

 
    

    

                  


Javascript
const htmlDOM = // Get the DOM of
                //the Target Markup
 
let errScr = htmlDOM.document
        .createElement('script');
 
errScr.type = 'text/javascript';
 
errScr.innerText =
    `window.addEventListener("error",
    errorLog);function errorLog(event)
    { //process the event object}`;
 
htmlDOM.document.querySelector
        ('body').append(errScr);


HTML


 

    
    

 

    
     
    

 


找到 HTML 代码(方法 1):

HTML



 

    
    
    Document

 

    

        No Errors     

                  

示例 – 方法 1

方法2:在这个方法中,我们将使用onerror Event Handler。

  • 步骤 1 —获取该 HTML 标记的正文标记,无论您是外部 HTML 标记还是当前加载页面的标记。
  • 第 2 步 —现在,当我们在 const 标识符中获得 body 标记时,比如 const bodyTag,我们将向 bodyTag 添加 onerror 事件处理程序。

Javascript

const bodyTag =
 
    // body tag of External HTML
    // Markup or of your page
    bodyTag.onerror = errorLogger;
 
function errorLogger(msg, url,
    lineNo, columnNo, error) {
 
    // Now process your Error
    // Information as you desire
}

您是否注意到上述两种方法的记录器函数的区别——通常在触发任何事件的情况下,附加到它的函数会收到一个事件对象,但在这种情况下(方法 2)我们会收到一个预先提取的信息(对于详细原因请参阅 MDN WebDocs)。

注意 —请记住 loggerFunction-Total 5 Information — Sequence 中收到的错误信息的顺序始终相同。

找到 HTML 代码(方法 2):

HTML



 

    
    

 

 
    

    

                  

示例 – 方法 2

方法 3:在此方法中,我们将向网页附加一个脚本元素。当我们希望错误记录器在特定时间激活或外部脚本执行等情况下,此方法很有用。

  • 第 1 步 —获取您所针对的标记页面的正文标签。
  • 步骤 2 —准备一个脚本元素并附加它。

Javascript

const htmlDOM = // Get the DOM of
                //the Target Markup
 
let errScr = htmlDOM.document
        .createElement('script');
 
errScr.type = 'text/javascript';
 
errScr.innerText =
    `window.addEventListener("error",
    errorLog);function errorLog(event)
    { //process the event object}`;
 
htmlDOM.document.querySelector
        ('body').append(errScr);

示例 – 方法 3

示例说明 — 方法 3:如您所见,我们使用 iframe 访问同一页面(同源)的 index.html,我们在 parentPage 中植入了一个脚本来记录另一个网页中的错误。

警告 — 尽管您将被阻止,但请注意在未经该页面所有者书面许可的情况下使用这些方法,以防 CROSS-SCRIPTING (CORS)(不同来源的脚本)。

找到 HTML 代码(方法 3):

HTML



 

    
    

 

    
     
    

 

重要的提示 –

  1. 您可以同时使用innerText 和innerHTML 来编写js 脚本,但我们建议使用innerText,因为脚本中的任何HTML 实体都会产生任何不需要的错误。
  2. 在方法三中,目标和获取方式在不同的情况下可能会有所不同。因此,用于实现此方法的代码可能略有不同,但方法将保持不变。