iOS 12.2更新致WebView无法在新浏览器窗口打开链接求助
问题分析与网页端解决方案
我之前也碰到过iOS 12.2 UIWebView的这个坑,你的问题核心在于:iOS 12.2在真实设备上对UIWebView处理target="_blank"链接的逻辑做了严格变更,而模拟器没有遵循这个新规则,才导致了真机和模拟器的差异。
问题根源
当用户点击带target="_blank"的链接时,iOS 12.2真机上的UIWebView会尝试创建一个全新的UIWebView实例来加载链接,但你的代理代码只绑定在了初始的WebView上。新生成的WebView没有设置UIWebViewDelegate,所以你的shouldStartLoadWithRequest方法完全不会被触发,自然也就不会执行openURL的跳转逻辑,导致点击后毫无反应。而模拟器可能还保留着旧的处理逻辑,直接在原WebView的代理里处理请求,所以一切正常。
无需更新App的网页端解决方案
既然没法修改App代码,我们可以通过网页端的JavaScript来绕开这个限制,让点击事件回到原WebView的代理流程中:
方案1:批量移除target="_blank"属性
把页面中所有带target="_blank"的链接改成在当前窗口加载,这样原生代理就能正常捕获请求并执行判断逻辑:
document.addEventListener('DOMContentLoaded', function() { // 处理页面已加载的静态链接 const staticBlankLinks = document.querySelectorAll('a[target="_blank"]'); staticBlankLinks.forEach(link => { link.removeAttribute('target'); // 也可以改成 target="_self",效果一致 // link.setAttribute('target', '_self'); }); // 处理后续动态生成的链接(事件委托) document.addEventListener('click', function(e) { const dynamicLink = e.target.closest('a[target="_blank"]'); if (dynamicLink) { dynamicLink.removeAttribute('target'); } }); });
方案2:拦截点击事件,手动触发跳转
如果需要保留target="_blank"的标记(或有其他业务需求),可以拦截点击事件,阻止默认的新窗口行为,改用window.location.href触发加载:
document.addEventListener('DOMContentLoaded', function() { // 处理静态链接 const staticBlankLinks = document.querySelectorAll('a[target="_blank"]'); staticBlankLinks.forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); // 阻止默认新窗口行为 window.location.href = this.href; }); }); // 处理动态链接(事件委托) document.addEventListener('click', function(e) { const dynamicLink = e.target.closest('a[target="_blank"]'); if (dynamicLink) { e.preventDefault(); window.location.href = dynamicLink.href; } }); });
这两种方案的核心都是让请求回到原WebView的代理流程中,确保你的shouldStartLoadWithRequest代码能正常判断是否要在外部浏览器打开链接。
内容的提问来源于stack exchange,提问作者timetofly
相关产品推荐
相关产品推荐

