如何在safari浏览器下用window.close()

本文介绍了一种解决在Safari浏览器中无法使用window.close()的问题的方法。通过添加特定的JavaScript代码,可以成功实现关闭窗口的功能。

最近在解bug时遇到这样一个问题,在js里面使用window.close(),IE浏览器中可以,但在safari中不可,经过调试可以这样写:

top.window.opener = null;

top.window.open('','_self','');

top.window.close();

很奇特啊,就只在原来的基础上加了

top.window.open('','_self','');

使问你是否关闭窗口的yes or no 的提示框丢掉就可以在safari浏览器中使用

window.close()了



你遇到的问题是: > 即使使用了 `window.childWindow.close()`,仍然报错。 这是浏览器安全机制的体现,说明你尝试关闭的窗口虽然由 `window.open()` 打开,但可能由于**跨域、窗口已关闭、或引用失效**等原因导致 `close()` 失败。 --- ## 🧨 可能的原因及排查方法 ### 1. ❗ 跨域访问限制(CORS) 如果你打开的子窗口是**跨域页面**(如 `https://otherdomain.com`),浏览器出于安全考虑,**即使你用 `window.open()` 打开的,也可能无法调用 `.close()`**。 #### ✅ 解决方法: - 确保打开的页面是**同源**(协议 + 域名 + 端口一致); - 或者让子窗口自己监听消息并主动调用 `window.close()`。 --- ### 2. ❗ 窗口已经关闭或被浏览器回收 你可能在子窗口关闭后再调用 `.close()`,或浏览器已回收该窗口资源。 #### ✅ 解决方法: 在调用 `.close()` 前检查窗口是否还存在: ```js if (window.childWindow && !window.childWindow.closed) { window.childWindow.close() } ``` --- ### 3. ❗ `window.childWindow` 引用失效或未正确赋值 你可能没有正确保存子窗口的引用,比如在 Vue 组件中,变量作用域限制了访问。 #### ✅ 解决方法: 确保在打开窗口时正确保存引用: ```js // 正确保存引用 window.childWindow = window.open('https://yourdomain.com', '_blank') ``` 或者使用 Vue 的全局变量/状态管理: ```js this.$store.commit('setChildWindow', window.open('...', '_blank')) ``` --- ### 4. ❗ 子窗口跳转导致 opener 被断开 如果子窗口加载后发生了跳转(如 Vue 路由跳转),浏览器可能会断开 `window.opener` 的连接,导致通信失败。 #### ✅ 解决方法: - 在子窗口首次加载时就保存 `window.opener`; - 或者使用 `BroadcastChannel`、`localStorage` 替代 opener。 --- ### 5.浏览器隐私模式或安全策略限制 某些浏览器(如 Safari、Chrome 隐私模式)对 `window.open()` 和 `.close()` 有更严格的限制。 #### ✅ 解决方法: - 使用替代通信方式(如 `BroadcastChannel`); - 或者在子窗口内监听消息并主动关闭自己: ```js // 子窗口中监听关闭消息 window.addEventListener('message', (event) => { if (event.origin !== 'https://yourdomain.com') return if (event.data === 'closeIframe') { window.close() } }) ``` --- ## ✅ 完整示例代码 ### 父窗口代码: ```js // 打开子窗口并保存引用 window.childWindow = window.open('https://yourdomain.com', '_blank') // 发送关闭消息 if (window.childWindow && !window.childWindow.closed) { window.childWindow.postMessage('closeIframe', 'https://yourdomain.com') } ``` ### 子窗口代码: ```js // 监听消息并关闭自己 window.addEventListener('message', (event) => { if (event.origin !== 'https://yourdomain.com') return if (event.data === 'closeIframe') { window.close() } }) ``` --- ## ✅ 总结 | 原因 | 是否影响 `.close()` | 解决方案 | |------|---------------------|----------| | 跨域 | ❌ | 使用同源或子窗口自己调用 `window.close()` | | 窗口已关闭 | ❌ | 检查 `childWindow.closed` | | 引用失效 | ❌ | 正确保存引用 | | 跳转导致 opener 断开 | ❌ | 子窗口保存 opener 或使用替代通信 | | 浏览器限制 | ❌ | 使用 `BroadcastChannel` 或提示用户关闭 | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值