【问题标题】:Catch SyntaxError exceptions when inserting script tags into DOM将脚本标签插入 DOM 时捕获 SyntaxError 异常
【发布时间】:2014-07-02 09:29:27
【问题描述】:

在单页 Web 应用程序中,有时需要将新的 javascript 块附加到页面。

假设我们有以下脚本标记内容,它们确实存在语法错误,例如缺少引号。一定是在解析时而不是运行时引发异常的错误。

var test = {"foo":1, "bar":"test, "baz":"foobar"};

现在,您创建一个新的脚本元素,将文本注入其中并将其附加到 DOM:

var text = 'var test = {"foo":1, "bar":"test, "baz":"foobar"};';        
var node = document.createElement('script');
node.appendChild(document.createTextNode(text));
head.appendChild(node);

当然,在最后一行,抛出一个“SyntaxError”异常。

问题在于将最后一行放在 try catch 块中不起作用,异常永远不会被捕获。我设法使用旧的脏 window.onerror 东西来捕获错误,但仅在 Chrome 上。例如,在 IE11 上,如果禁用了脚本错误,则它仅在控制台打开时有效。

所以问题是,如何可靠地捕获此异常以便能够向用户呈现消息?

谢谢

【问题讨论】:

  • “问题在于将最后一行放在 try catch 块中不起作用,永远不会捕获异常” - 当然不是,因为那不是行这导致了错误(这里没有异常) - 将脚本节点附加到 head 元素已经出色地工作得很好,那里没有出错。

标签: javascript exception dom syntax-error


【解决方案1】:

为了捕获 SyntaxError,您可以使用 window.addEventListener('error', ...) 方法并防止默认值。一些示例代码:

var sourceCode = ...;

await new Promise((resolve, reject)=>{               

            var script = document.createElement('script');
            script.type = 'module';
            script.innerHTML = sourceCode + '\n' + 
                               'if(window.scriptLoadedHook){window.scriptLoadedHook();}';               


            var windowErrorHandler = (event) =>{
                event.preventDefault();
                var error = event.error;
                error.stack = error.stack + '\n\n' + sourceCode;                    
                window.removeEventListener('error', windowErrorHandler);
                reject(error);
            };

            window.addEventListener('error', windowErrorHandler);  

            var rejectHandler = (error) =>{
                window.removeEventListener('error', windowErrorHandler);
                reject(error);                  
            };              

            script.addEventListener('error', rejectHandler);
            //script.onerror = rejectHandler;

            script.addEventListener('abort', rejectHandler);
            //script.onabort = rejectHandler;
                         

            var loadedHandler = ()=>{
                window.removeEventListener('error', windowErrorHandler);
                resolve();
            };

            script.addEventListener('load', loadedHandler);
            script.onload = loadedHandler;

            var body = document.getElementsByTagName('body')[0];
            try {
                body.appendChild(script); 
            } catch(error){
                reject(error);
            }               

        })
        .catch(error => {
            console.warn('Could not process JavaScript code:\n', error);
        })
        .then(()=>{
            //refresh app etc.;
        });                 
        
    });        

【讨论】:

    【解决方案2】:

    不确定是否有办法捕获它,但如果您可以控制加载的脚本,您当然可以使用以下解决方法知道何时发生任何错误。

    问题是 SyntaxError 没有通过“onerror”,而是通过“onload”完成。 所以 hack 是在源脚本的末尾插入一个小标志/赋值语句,并在“onload”回调期间检查标志,除了用“onerror”捕获其他错误。

    【讨论】:

      猜你喜欢
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 2015-02-10
      • 1970-01-01
      • 2021-08-06
      • 2012-05-28
      • 1970-01-01
      • 2011-11-08
      相关资源
      最近更新 更多