【问题标题】:Catching SyntaxError caused by bad JS loaded via jQuery.load()捕获通过 jQuery.load() 加载的错误 JS 导致的 SyntaxError
【发布时间】:2015-06-26 11:46:16
【问题描述】:

我有一个 Javascript 控件,它加载一个包含 HTML 的页面和一些只有该页面需要的 Javascript。

最初我在YAGNI/KISS 假设下进行操作,并将所有 Javascript 保存在一个大的functions.js 文件中;但是现在页面的数量已经增加了,而且其中有几个是变体,需要对相同的函数进行稍微不同的实例化。

所以我会觉得能够写作很有用

 <div>...<button id="object123">Don't click me!</button>... </div>
 <script>
     $('#object123').on('click', function(){
         alert("I said not to click!");
     });
 </script>

并加载它

 // All error checking omitted for clarity
 $(divSelector).load('page-with-object-123.html');

鉴于我已经对 ID 的唯一性等进行了检查,如果 脚本包含语法错误,就会出现问题。在那种情况下,当然执行会停止,但更重要的是,我在 jQuery 中得到一个错误 .load 执行 &lt;script&gt; 标记的位置)。因此,不能立即将错误追溯到原始 HTML。

能够得到错误(就此而言,我的脚本中唯一的语法错误现在是故意的),但我想抓住它以便优雅地处理它。

我已经用try/catch 尝试了显而易见的方法

try {
    $(divSelector).load(sourceHTML);
} catch (err) {
    alert("An error occurred in " + sourceHTML);
}

但没有发现错误。 This answer 建议它应该是,除非 jQuery 对 try/catch 机制做了一些奇怪的事情。

然后我按照this other answer 的建议尝试使用window.onerror。在其默认化身中它可以工作(即我在全局范围内定义 onerror 回调)。

那时我试图改变函数体本身,并在不再需要处理程序时恢复它。

虽然它诱人地似乎工作了一次(可能是因为由于客户端缓存,我正在查看一个较旧的全局版本的代码),但我似乎无法让它工作。

小心的在强制的facepalm之后只在调用真正发出之后恢复处理程序.

/**
 * Effect a call 
 * @param string    op*        command
 * @param dict      data       data to send
 * @param callable  callback   function to be called on success 
 * @param callable  onError    function to be called on failure
 */
function poster(op, data, callback, onError) {
    // Save handler
    var origHandler = window.onerror;
    // Install new error handler
    window.onerror = function(message, url, lineNumber) {
        alert(message + "\n" + url + "\n" + lineNumber);
        return true;
    };
    $.post(
        ajaxUrl,
        $.extend({ op: op }, data),
        function (responseText, statusText, jqXHR) {
            // Evaluate the response for server error notifications
            var todo = jqBadResponse(responseText) ? onError : callback;
            // Edit: try using onerror to watch also callbacks.
            // window.onerror = origHandler;
            todo && todo(responseText);
            // Restore error handler
            window.onerror = origHandler;
        }
    ).fail(function(jqXHR, title) { // Outer failure.
        // Restore error handler
        window.onerror = origHandler; 
        jqCheckFail(jqXHR, title); // Notify of the error
    });
}

我知道what my basic problem is...我知道的是,在这种情况下在哪里

【问题讨论】:

    标签: javascript jquery html ajax


    【解决方案1】:

    仔细检查在 Stack Overflow 上发布合理问题的要求通常会产生副作用——你会偶然发现答案

    正如我所说,我使用了一个函数来将 HTML 加载到 DIV 中。但是现在有了上面的函数我做的不一样。实际赋值不再由.load() 中的jQuery 完成而是由我自己的回调完成

    jQuery 将解释 Javascript 并在 .html() 调用中抛出 SyntaxError ,而不是在 .load() 调用中。在 .load 函数内部,加载的 HTML 代码只是一个字符串,它包含的任何语法错误都会被忽略。

    当我告诉 jQuery 将该字符串视为 HTML 并将其放入 DOM 时,就会引发异常。当我在 .post 函数中时,这确实发生了,但它发生在范围内更远的地方。

    我仍然不太明白为什么外部的try {} 未能捕捉到它,但我有理由相信这可能与以下事实有关

    try (
        var a = ...*some Promise whose payload will be executed sometime in the near future*...
    } catch (e) {
        // Here I catch the error and there is no error;
        // the Promise did promise the impossible, but that
        // offer hasn't been picked up yet.
    }
    ...
    // NOW finally the Promise executes and throws. But I'm no longer inside
    // a try/catch block.
    

    确实,如果我将 try/catch 放在同步块中

    poster(
        'form',
        {
            code:  ...,
            id:    ...
        },
        function (responseText) {
            try {
                $('#details').html(responseText.data.html);
            } catch(e) {
                alert("GOTCHA");                
                return;
            }
            ...
        }
    );
    

    异常被正确捕获。

    【讨论】:

      猜你喜欢
      • 2015-05-09
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-01
      • 2012-08-09
      • 2020-04-06
      相关资源
      最近更新 更多