使用"location.href"取消页面卸载时出现"未知异常"

djd*_*d87 5 javascript asp.net onbeforeunload

我正在使用以下代码捕获window.onbeforeunload事件:

window.onbeforeunload = function (evt) 
{

    if(checkIsDirty())
        { 
            var message = 'If you continue your changes will not be saved.'; 
            if (typeof evt == 'undefined') 
            {   
                //IE 
                evt = window.event; 
            } 
            if (evt) 
            { 
                evt.returnValue = message; 
            }
            else
            {
                return message; 
            }
        }

} 
Run Code Online (Sandbox Code Playgroud)

当我在结果确认中单击"取消"时,我收到错误"未知异常",调试器突出显示以下内容:

onclick="location.href='/<WhicheverPageYouRequested>.aspx';
Run Code Online (Sandbox Code Playgroud)

如果单击"确定",页面将完全更改.为什么我会收到此错误,我该如何解决?

bob*_*nce 9

是的,这是一个已知的IE行为.当您尝试从JavaScript导航时(使用location,location.href,location.replace,document.location,history,甚至是诸如link.click或form.submit之类的环形交叉方法),beforeunloadCancel将引发异常.测试用例很简单:

window.onbeforeunload= function() { return '?'; }
location.href= 'http://www.example.com/';
Run Code Online (Sandbox Code Playgroud)

这可能是故意的,让脚本知道导航尝试失败,除了错误名称是如此完全无用.(我得到"未指定的错误".)

传统的解决方案就是抓住它:

try {
    location.href= '...';
} catch(e) {}
Run Code Online (Sandbox Code Playgroud)

我总是怀疑这一点虽然捕获所有异常通常都是坏消息(但是IE不允许你只捕获这个异常......没有检查确切的stringTo,这是非常脆弱的.

另一种方法是将onbeforeunload工作移动到调用代码,以便真正的onbeforeunload永远不会发生,并且没有异常:

function navigate(url) {
    if (window.onbeforeunload) {
        if (confirm(window.onbeforeunload()+' Press OK to continue, or Cancel to stay on the current page.')
            window.onbeforeunload= '';
        else
            return;
    }
    location.href= url;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您正在使用的任何框架插入代码,而不是您自己编写的内容,那么任何一种解决方案都可能超出您的掌握范围.

onclick="location.href='/<WhicheverPageYouRequested>.aspx'";
Run Code Online (Sandbox Code Playgroud)

这是什么样的控制?它本身看起来很可疑:当然,你点击进入另一个页面的东西应该被标记为一个简单的链接,而不是一个JavaScript-onclick元素(这些元素在很多方面出错).如果它是一个简单的非JavaScript链接,您不必担心IE错误.

顺便提一下,你的beforeunload函数可能会在非IE浏览器上失败(returnValue只是IE浏览器).它似乎有点过于复杂......出了什么问题:

window.onbeforeunload= function() {
    if(checkIsDirty())
        return 'If you continue your changes will not be saved.';
}
Run Code Online (Sandbox Code Playgroud)