Flutter webview_flutter加载网页无法打开URL Scheme问题咨询
问题原因
webview_flutter 作为嵌入式网页渲染组件,默认导航策略和系统浏览器存在本质差异:
- 系统浏览器内置了通用URL Scheme路由规则,遇到
tel、mailto、sms这类非HTTP/HTTPS请求时,会主动交给系统路由模块唤起对应应用,因此可以正常触发跳转。 - webview_flutter 默认仅支持加载HTTP/HTTPS协议的资源,所有非HTTP/HTTPS的导航请求会被直接拦截丢弃,不会主动触发系统级的应用唤起逻辑,这是跳转失败的核心原因。
- 网页侧集成的
url_launcher插件(Web端实现)本质是调用浏览器标准跳转API,这个API在webview环境下受上述默认策略限制,无法绕过拦截直接唤起外部应用。
修复方案
你需要在集成webview_flutter的宿主APP侧做配置,拦截自定义Scheme请求并手动触发系统唤起能力,网页侧代码不需要额外修改。
- 配置WebView导航委托
初始化WebViewController时设置导航拦截逻辑,识别需要外部唤起的Scheme,手动调用系统能力跳转,同时阻止WebView内部加载这类请求:
import 'package:url_launcher/url_launcher.dart'; import 'package:webview_flutter/webview_flutter.dart'; final WebViewController webViewController = WebViewController() ..setNavigationDelegate( NavigationDelegate( onNavigationRequest: (NavigationRequest request) async { final Uri targetUri = Uri.parse(request.url); // 按需扩展需要支持的外部Scheme列表 const externalSchemes = ['tel', 'sms', 'mailto', 'weixin']; if (externalSchemes.contains(targetUri.scheme)) { if (await canLaunchUrl(targetUri)) { await launchUrl( targetUri, mode: LaunchMode.externalApplication, ); } // 拦截请求,禁止WebView内部加载 return NavigationDecision.prevent; } // HTTP/HTTPS请求正常在WebView内加载 return NavigationDecision.navigate; }, ), ) ..loadRequest(Uri.parse('你部署的网页地址'));
- Android端权限配置
在android/app/src/main/AndroidManifest.xml的<manifest>节点下(和<application>节点平级)添加查询权限声明,否则canLaunchUrl会无法识别目标应用:
<queries> <intent> <action android:name="android.intent.action.DIAL" /> <data android:scheme="tel" /> </intent> <!-- 其他第三方Scheme对应添加匹配的intent声明即可 --> </queries>
- iOS端权限配置
在ios/Runner/Info.plist中添加可查询的Scheme白名单:
<key>LSApplicationQueriesSchemes</key> <array> <string>tel</string> <string>sms</string> <string>mailto</string> <!-- 其他第三方Scheme添加到此处 --> </array>
说明:以上配置对所有在WebView中加载的网页生效,不管网页是Flutter编译的Web产物,还是原生开发的普通H5页面,只要触发对应Scheme的跳转请求都会被正确拦截处理。
内容的提问来源于stack exchange,提问作者Liu Silong
相关产品推荐
相关产品推荐

