ie 被呼叫方不可用并已消失

96
低至一折起
2017.12.05 18:01 字数 1156

故障现象

在B/S Web系统中,管理员重复在同一台机器上登录功能,会导致脚本报错。具体表象为:Java Script Error 被呼叫方(服务器[不是服务器应用程序])不可用并已消失。所有连接均无效。没有执行呼叫。或没有执行权限

实现技术

一般在B/S系统中,在管理员登录打开主操作页面窗口之前,从实现技术上,一般是首先打开登录页面窗口,登录验证成功后,才打开一个全屏主操作页面窗口,在这里为了后面说明的方便,我们可以称打开主操作页面窗口之前的登录窗口,为引导窗口;同时,被打开的主操作页面窗口具有同样的窗口名字,一般同名的IE窗口用来控制同一台机器只有一个账户登录,也就是说即使两个管理员在同一台机器上登录,也只有一个主窗口被打开。如果这时,我们假设另外一个管理员也在同一台机器上登录,他首先会手动打开了登录窗口,然后提交数据,在后期登录流程通过B/S系统JavaScript window.open脚本代码打开主操作页面窗口时,由于IE检测到具有同名的IE窗口已经存在,所以实际发生的行为就是冲掉前面已经存在的同名窗口内容,重新加载新的数据,而不是新创建一个新窗口。这样的特性,也经常被用来控制同一个机器上仅允许一个管理员登录。

登录过程形式化

引导窗口1----->主窗口(同名窗口)--->加载完成后关闭引导窗口(通过opener属性) 引导窗口2----->主窗口(同名窗口)--->加载完成后关闭引导窗口(通过opener属性) 从形式化的过程来看,两个在同一台机器上登录的管理员过程,虽然引导窗口是不同的,但是最终呈现给用户的主操作页面窗口,由于是同名的,管理员的主操作页面窗口一定只有一份存在。

故障原因(也令人迷惑)

在IE的窗口属性中特殊有opener这样一个属性,记录其打开窗口,即创建此窗口的父窗口。在管理员重复登录这个场景下,IE浏览器就发生一个令人迷惑的问题,即在第二个登录过程发生后,虽然主窗口的内容已经被替换为第二个管理员的数据,但是主窗口的opener属性有很大可能还是引导窗口1,并没有得到更新,不是指向引导窗口2!!由于从概念上来讲,opener应该是引导窗口2才符合程序员对此过程的假定。所以,由于这个条件的不满足,程序原来的假定就出现了破裂,一定会出现水土不服的,而且错误通常会稀奇古怪,呵呵!这样,加载完成后在通过opener属性关闭引导窗口时,由于opener属性引用一个"尸体",所以前面的脚本报错故障就不难解释了! 补充一下,根据一个朋友的交流和研究,在此种场景下window脚本对象里面中的其它属性也有可能是Invalid的。 另外,报的脚本报错提示"被呼叫方",这主要是IE两个窗口间通讯数据时体现为一个远程过程调用或者内部消息通讯机制的原因,具体内部机制有待以后进一步研究。

解决办法

在引导窗口中,通过window.open返还的主窗口句柄,更新其opener属性 伪码
chilid = window.open(url,"main");
child.opener = window.self/注意,这里赋值chili.opener属性,也有非常小的几率涉及到多线程访问的难题/

附带其它研究结果

<script>脚本块,在出现脚本错误后其后面的所有脚本都不会被解析,但是范围仅是此script块,不会跨script块

Javascript
Web note ad 1