简体   繁体   English

通过jQuery.load()加载错误的JS导致捕获SyntaxError

[英]Catching SyntaxError caused by bad JS loaded via jQuery.load()

I have a Javascript control that loads a page containing HTML and some Javascript needed only by that page. 我有一个Javascript控件,可加载包含HTML和该页面仅需要的一些Javascript的页面。

Initially I operated under YAGNI /KISS assumptions and kept all the Javascript in a single large functions.js file; 最初,我在YAGNI / KISS假设下进行操作,并将所有Javascript都保存在一个大的functions.js文件中; but now the number of pages has grown, and moreover, several of them are variations that need slightly different instantiations of the same functions. 但是现在页面的数量增加了,而且其中一些是变体,需要对相同功能的实例化稍有不同。

So I would find it very useful to be able to write 所以我觉得能够写非常有用

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

and load it with 并加载它

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

Given that I already have checks in place for uniqueness of IDs et cetera, a problem arises if the script contains a syntax error . 鉴于我已经检查了ID等的唯一性,如果脚本包含语法错误 ,则会出现问题。 In that case of course execution stops, but what's more, I get an error inside jQuery (the point where the .load executes the <script> tag). 在这种情况下,当然会停止执行,但更重要的是,我在jQuery中收到一个错误( .load执行<script>标记的位置)。 So it is not immediate to track down the error to the originating HTML. 因此,立即查找错误到原始HTML并不是立即的。

I am able to get the error (for that matter the only syntax error in my scripts is now intentional), but I'd like to catch it in order to handle it gracefully. 能够得到的错误(为此事在我的脚本只有语法错误,现在是故意的),但我想抓住它,以便适当地处理它。

I have tried the obvious with try/catch 我用try/catch尝试了显而易见的方法

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

but the error isn't caught. 但没有发现错误。 This answer would suggest it should have been, unless jQuery does something weird to the try/catch mechanism. 这个答案表明应该如此,除非jQuery对try / catch机制做一些奇怪的事情。

I have then tried using window.onerror as suggested by this other answer . 然后,我尝试使用其他答案建议的window.onerror In its default incarnation it works (ie I define the onerror callback globally). 它以其默认形式运行 (即,我全局定义了onerror回调)。

At that point I tried to effect the change in the function body itself, and have the handler restored once it was no longer needed. 那时,我试图实现功能主体本身的更改,并在不再需要处理程序时对其进行恢复。

While it tantalizingly appeared to have worked once (possiby because I was looking at an older, global version of the code due to client caching), I can't seem to make it work. 尽管它似乎曾经曾经工作过一次(这很可能是因为我正在查看由于客户端缓存而导致的较旧的全局版本的代码),但我似乎无法使其正常工作。

I was careful after the mandatory facepalm to restore the handler only after the call had been really issued. 只有真正发出呼叫之后,强制性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
    });
}

I know what my basic problem is ... what I don't know, is where it is in this case. 我知道我的基本问题是 ……在这种情况下,我知道的地方是什么。

The usual side-effect of carefully checking the requirements for posting a sensible question on Stack Overflow -- you stumble on the answer . 仔细检查有关在Stack Overflow上发布明智问题的要求的通常的副作用- 您迷失了答案

As I said, I used a function to load a HTML into a DIV. 正如我所说,我使用了一个将HTML加载到DIV中的函数。 But now with the above function I do that differently . 但是现在通过上面的函数我可以做到了 The actual assignment is no longer done by jQuery in .load() but by my own callback . 实际的赋值不再由jQuery在.load()完成, 而是由我自己的callback完成

And jQuery will interpret the Javascript and throw a SyntaxError in the .html() call , not in the .load() call anymore. jQuery将解释Javascript并.html()调用中抛出SyntaxError,而不再在.load()调用中抛出SyntaxError。 Inside the .load function, the loaded HTML code is just a string, and whatever syntax errors it contains are ignored. .load函数内部,加载的HTML代码只是一个字符串,并且忽略其中包含的任何语法错误。

It's when I tell jQuery to consider that string as HTML and place it in the DOM that the exception is thrown. 当我告诉jQuery将字符串视为HTML并将其放置在DOM中时,就会引发异常。 This does happen while I'm inside the .post function, but it happens farther down in the scope. 确实发生 ,而我的里面.post的功能,但它发生在范围更远了。

I still don't quite understand why the outer try {} failed to catch it, but I'm reasonably confident this may have to do with the fact that 我仍然不太明白为什么外部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.

Indeed if I place the try/catch in a synchronous block 确实,如果我将try / catch放在同步块中

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

the exception is correctly caught. 异常已正确捕获。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM