当前位置: 首页 > news >正文

IOS 安全机制拦截 window.open

摘要

在ios环境,在某些情况下执行window.open不生效

一、window.open

window.open(url, target, windowFeatures)

1. url:「可选参数」,表示你要加载的资源URL或路径,如果不传,则打开一个url地址为about:blank的空白页。

2. target:「可选参数」,它可以给以下两种值

第一种是target关键字
_self:当前标签页加载;
_blank(默认值):新标签页打开;
_parent:作为当前浏览环境的父级浏览上下文打开,没有父级浏览上下文,效果与_self相同;
_top:作为最顶级的浏览上下文打开,没有顶级浏览上下文,效果与_self相同。
第二种是一个字符串:
表示加载资源的浏览上下文的名称,也就是标签页的名称,如果这个名称在现有的标签页中不存在,则会开启一个新的标签页,如果存在,会跳转到这个标签页。

3. windowFeatures:「可选参数」,它是一个字符串,用来描述窗口的特性,其格式是"key1=value1, key2=value2",即将key和value以=号连接拼接成字符串,多个key value以逗号隔开,比如我们要打开一个宽为500,高为600的窗口可以这么写:

window.open(url, 'new-window', 'width=500,height=600');

二、Bug

复现问题的demo:

async function jump() {await fetch('/xxx');window.open('https://www.xxx.cn');
}

正常情况下执行window.open是能正常新标签页打开传入的url的,但是一旦前面用await做了异步操作后,再执行window.open,就不生效了。

三、原因分析

  • 安全机制拦截:IOS的Safari浏览器为了防止恶意网站通过window.open/a标签打开其他网站,于是对它们的调用有所限制,如果不是由用户直接交互触发的,而是由程序自动触发的,Safari会拦截这个操作。
  • 异步操作:在AJAX回调中执行window.open/a标签跳转,被浏览器认为是非用户交互行为,所以被拦截。

四、解决方案

方案1:改用location.href
async function jump() {await fetch('/xxx');location.href = 'https://www.xxx.cn';
}

safari不会拦截location.href

并不是所有场景下都适合用location.href,因为location.href会刷新页面,所以需要根据具体场景来选择。

方案2:先打开一个空标签页
async function jump() {const newWin = window.open("", "_blank"); // 提前打开一个窗口const { jumpUrl } = await fetch('/xxx');if (jumpUrl) {newWin.location = jumpUrl;} else {newWin.close();// ... }
}

这里根据有没有jumpUrl进行跳转,如果没有jumpUrl,我需要调用close方法关闭刚才提前打开的那个窗口,而这样用户就会体验到的流程就是,先出来一个新窗口,随后被秒关闭,这样用户体验很差。

方案3:setTimeout/requestAnimationFrame
async function jump() {await fetch('/xxx');setTimeout(() => {window.open('https://www.xxx.cn');}, 0)
}
async function jump() {await fetch('/xxx');requestAnimationFrame(() => {window.open('https://www.xxx.cn');})
}

五、总结

如果setTimeout不生效,可以尝试加点延时看看,比如100毫秒,我这边实测的ios机型都能生效,所以就没加延时。

http://www.lryc.cn/news/525696.html

相关文章:

  • jmeter中对接口进行循环请求后获取相应数据
  • 【QT】-explicit关键字
  • 【深度学习】 自动微分
  • 字节跳动自研HTTP开源框架Hertz简介附使用示例
  • skynet 源码阅读 -- 核心概念服务 skynet_context
  • 每日十题八股-2025年1月23日
  • MongoDB部署模式
  • opencv笔记2
  • springboot使用ssl连接elasticsearch
  • Linux内核中的InfiniBand核心驱动:verbs.c分析
  • 把网站程序数据上传到服务器的方法和注意事项
  • 完全平方数——唯一分解定理
  • (详细)Springboot 整合动态多数据源 这里有mysql(分为master 和 slave) 和oracle,根据不同路径适配不同数据源
  • mock可视化生成前端代码
  • Spring Boot(6)解决ruoyi框架连续快速发送post请求时,弹出“数据正在处理,请勿重复提交”提醒的问题
  • 鸿蒙Harmony json转对象(1)
  • 常见的RocketMQ面试题及其简要答案
  • C#Object类型的索引,序列化和反序列化
  • Unity3D项目开发中的资源加密详解
  • 微调Qwen2:7B模型,加入未知信息语料
  • 【Ubuntu】安装SSH启用远程连接
  • 【理论】测试开发工程师进阶路线
  • 【BQ3568HM开发板】如何在OpenHarmony上通过校园网的上网认证
  • 動態住宅IP提升網站訪問成功率
  • 2024年博客之星主题创作|2024年蓝桥杯与数学建模年度总结与心得
  • Spring Boot/MVC
  • 由于请求的竞态问题,前端仔喜提了一个bug
  • 【Day25 LeetCode】贪心Ⅲ
  • 蓝桥杯练习日常|递归-进制转换
  • AI Agent:深度解析与未来展望