webview_flutter如何拦截window.open或target="_blank"的跳转请求
解决方案:用webview_flutter拦截window.open和target="_blank"跳转
核心思路
通过注入自定义JavaScript代码,重写window.open方法并监听所有带target="_blank"的链接点击,把跳转请求传递给Flutter端处理,同时阻止浏览器的默认新窗口行为。
具体实现步骤
1. 创建JavaScriptChannel接收Web端跳转请求
初始化WebView时,创建一个JavaScriptChannel,用于接收Web页面发送的新窗口跳转URL:
final JavaScriptChannel _newWindowChannel = JavaScriptChannel( name: 'NewWindowChannel', onMessageReceived: (JavaScriptMessage message) { final String targetUrl = message.message; // 在这里处理拦截到的新窗口请求,比如: // - 在当前WebView加载该URL // - 调用外部浏览器打开 // - 直接阻止跳转 print('拦截到新窗口请求: $targetUrl'); }, );
2. 注入JS代码拦截跳转行为
在WebViewController的onWebViewCreated回调中,注入自定义JS代码,实现双重拦截:
void _onWebViewCreated(WebViewController controller) { _controller = controller; // 注入拦截新窗口跳转的JS代码 controller.runJavaScript(''' // 重写window.open,拦截调用并传递URL到Flutter window.open = function(url) { NewWindowChannel.postMessage(url); // 返回空对象阻止浏览器创建默认新窗口 return { closed: false }; }; // 拦截所有target="_blank"的a标签点击 document.addEventListener('click', function(e) { const targetLink = e.target.closest('a'); if (targetLink && targetLink.getAttribute('target') === '_blank') { e.preventDefault(); const url = targetLink.getAttribute('href'); url && NewWindowChannel.postMessage(url); } }, true); '''); }
3. 配置WebView参数
将JSChannel添加到WebView,并启用JavaScript支持:
WebView( initialUrl: '你的目标网页URL', onWebViewCreated: _onWebViewCreated, javascriptMode: JavaScriptMode.unrestricted, javascriptChannels: {_newWindowChannel}, navigationDelegate: NavigationDelegate( onNavigationRequest: (request) { // 这里可继续处理普通跳转请求 return NavigationDecision.navigate; }, ), )
补充说明
- 监听点击事件时使用了捕获阶段(第三个参数为
true),确保能在浏览器默认行为触发前完成拦截 - 如果页面存在动态渲染的内容(如Ajax加载的链接),可以将监听逻辑封装成函数,在内容更新后重新执行,或使用事件委托覆盖动态生成的元素
- 在
onMessageReceived回调中,可根据业务需求灵活处理拦截到的URL,无需依赖onNavigationRequest的模糊判断
内容的提问来源于stack exchange,提问作者Thang Phi
相关产品推荐
相关产品推荐

