如何从iFrame中获取自定义URL scheme数据并拦截调用报错
实现方案
可以实现,不需要依赖浏览器扩展,仅通过页面层面的JS监听即可完成拦截和URL提取,有两种适配不同场景的方案:
方案1:全局错误事件监听(适配所有场景,操作最简便)
Chrome抛出的自定义scheme未注册错误属于全局可捕获的错误事件,你可以在顶层页面的window对象上开启捕获阶段监听,通过匹配错误文本提取目标URL,不会触发外部应用拉起:
window.addEventListener('error', (event) => { // 匹配该类错误的固定文本格式,提取URL const schemeErrorRegex = /Failed to launch '([^']+)' because the scheme does not have a registered handler/; const matchResult = event.message.match(schemeErrorRegex); if (matchResult) { const customSchemeUrl = matchResult[1]; // 此处写入你的自定义处理逻辑 console.log('成功拦截到未注册scheme URL:', customSchemeUrl); // 可选:阻止错误继续输出到控制台 event.preventDefault(); } }, true); // 第三个参数设为true开启捕获,才能拿到iframe内抛出的跨上下文错误
该方案对同域、跨域iframe抛出的该类错误均生效,不需要对iframe做任何修改
方案2:iframe内部跳转拦截(适配可注入脚本的可控iframe场景)
如果页面内的iframe支持你注入自定义脚本,你可以直接在iframe上下文内覆盖跳转逻辑,在错误抛出前就拦截自定义scheme调用:
// 以下代码需要注入到iframe内部执行 // 拦截window.open触发的scheme跳转 const nativeWindowOpen = window.open; window.open = function (url, ...rest) { // 识别非HTTP/HTTPS的自定义scheme if (!url.startsWith('http:') && !url.startsWith('https:')) { console.log('拦截到window.open触发的scheme URL:', url); // 终止跳转逻辑,不会触发应用拉起 return null; } return nativeWindowOpen.apply(this, [url, ...rest]); }; // 拦截a标签点击触发的scheme跳转 document.addEventListener('click', (e) => { const linkNode = e.target.closest('a'); if (linkNode && !linkNode.protocol.startsWith('http')) { e.preventDefault(); console.log('拦截到a标签触发的scheme URL:', linkNode.href); } }, true);
该方案不会触发控制台报错,性能优于全局错误监听,但仅适用于你有权限注入脚本的同域iframe,或是配置了allow-scripts权限的可控跨域iframe
内容的提问来源于stack exchange,提问作者Adam Neuwirth
相关产品推荐
相关产品推荐

