iOS设备下JavaScript调用tel、email协议唤起电话/邮件失效问题
问题原因
这个问题本质是iOS端WebKit内核的特殊兼容逻辑+API误用共同导致的:
- 首先你用错了
window.location.assign的API:这个方法的标准语法只接收1个URL参数,根本没有第二个指定打开目标的参数,你写的_self是window.open方法的参数,属于无效传参。 - 桌面端全平台浏览器、安卓端WebView都会自动忽略这个无效参数,正常执行特殊协议的唤起逻辑,但iOS端所有浏览器(包括Safari、Chrome、微信内置浏览器等,苹果强制iOS所有第三方浏览器必须使用WebKit内核)对
tel:、mailto:这类唤起系统原生应用的特殊scheme有严格校验:只要调用跳转的API传参不符合规范,就不会触发系统应用唤起,反而把这个scheme地址当成普通网页地址处理,直接触发当前页面重载。 - Mac端的Safari用的是桌面版WebKit内核,没有加这层移动端专属的特殊scheme校验,所以写错参数也能正常唤起邮件应用,只有iOS端会触发这个问题。
- 额外注意:就算参数写对了,如果跳转逻辑放在异步回调(比如接口请求返回后、setTimeout回调里)执行,iOS也会因为丢失了用户点击的直接交互上下文,拦截原生应用的唤起,这也是iOS端特有的安全限制。
修复方案
直接改成下面任意一种写法即可全平台兼容:
- 最稳妥的全兼容写法,直接赋值location.href,不存在API参数问题:
// 拨打电话 window.location.href = "tel:" + telephone; // 唤起邮件 window.location.href = "mailto:" + email;
- 如果要继续用
assign方法,删掉多余的第二个参数就行——assign本身默认就是在当前页面跳转,不需要额外指定打开目标:
window.location.assign("tel:" + telephone);
不要用
window.open实现这类唤起,iOS默认会把window.open触发的跳转当成恶意弹窗拦截,基本无法正常唤起应用。
内容的提问来源于stack exchange,提问作者innom
相关产品推荐
相关产品推荐

