项目中使用的窗口组件加载内容是使用iframe
实现的, 以前遇到的各种问题总是在IE下, 但是之前又发现一个很奇怪的问题, 仅在Firefox下出现.
具体表现为窗口组件关闭时再将相关的父级或iframe
重定向到新的地址, 结果在Firefox下没看到重定向, 也没在错误控制台看到任何错误信息.
前提: 以下所有的都不涉及跨域的问题, 只描述Firefox下运行的情况, 目前我的Firefox版本是15.0.1.
关键结构如下, $
表示jQuery:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
一些需要说明的实际情况
- 窗口是指顶级页面的
window
和iframe
中的window
. 窗口下是指window.document
和下面的所有DOM元素. - 在
#main
中parent.dialog()
实际是自动探测或指定在哪个父级打开窗口.- 在
Dialog1
中parent.dialogClose
实际是哪个窗口打开就重定向那个窗口, 或者指定重定向哪个窗口.
- 在
<iframe id="Dialog1">
是按照实际打开的情况自动分配的id, 这里使用固定的id方便说明.
上述代码运行后的结果没有产生重定向, 加了try catch
后:
An error occurred throwing an exception
出错行在 (frameElement.openWindow || window).location = url;
.
怀疑可能是不能识别默认属性, 换成location.href
试试
"Component returned failure code: 0x804b000a (NS_ERROR_MALFORMED_URI) [nsIDOMLocation.href]"
在MDN window.location发现有assign
和replace
也可以用来重定向
assign
正常执行了, 但是replace
"Component returned failure code: 0x804b000a (NS_ERROR_MALFORMED_URI) [nsIDOMLocation.replace]"
想到可能和上下文有关吧, 试试用目标window.setTimeout
, 传入字符串参数, 执行正常了.
1
|
|
上述所有尝试的代码示例:
- 所有
iframe
加载的页面都在这一个里面, 根据不同的Url Query执行不同的代码. openWindow.
表示重定向的是按钮所在窗口.- 水平分割线下面的是重定向当前窗口.
- 蓝线以下是一些输出的信息, 以及发生异常时的异常信息.
- 重定向成功会显示一个红色背景的成功, 发生异常会在日志中显示出来.
- 重定向成功后, Result标签页右边有个Run again可以恢复开始状态.
另一方面
虽然问题算是解决了, 但是为什么在哪种情况会发生异常, 仅在Firefox下. 还有没有其它可以回避这个异常的方式.
想想上面代码有些怪怪的就是, 先从DOM树中移除了iframe
, 如果想办法调整一下移除和重定向的顺序, 就有了下面的示例:
可以看到所有的重定向都成功了.
总结
- 尽量避免使用
iframe
. - 尽量使用一种方式进行跨
iframe
间的调用, 比如setTimeout方式.- 调用参数尽量用基本类型, 比如字符串, 数字, 复杂的可以用JSON格式字符串.
- 尽量规避从DOM树移除当前
iframe
后还需要执行代码的情况.- 实在无法规避就需要十分注意前后的执行顺序.
当然如果和我一样是维护原有项目, 有很多地方不能随便修改, 遇到麻烦就只能大量摸索了. 比如上文中的尝试.
附:使用location的assign()和replace()的注意点
在iframe
中location.assign()
必须确保当前iframe
已加载一个页面, 不然会发生错误
"Component returned failure code: 0x804b000a (NS_ERROR_MALFORMED_URI) [nsIDOMLocation.assign]"
对于已加载页面的则正常, 例子: