有模有样解决Flutter里Webview无法访问HTTP页面的问题
共 3772字,需浏览 8分钟
·
2021-06-27 21:51
探索过程
Android9(好像是吧)开始谷歌就默认不让开发者访问不安全HTTP内容了,如果非要用HTTP,那必须在networkSecurityConfig
里配置cleartextTrafficPermitted
才行。谷歌这个设计的出发点本是好的,HTTPS固然更安全咱都懂,但有时候这个后端接口你选择不了要HTTP还是HTTPS,比如要使用没有提供HTTPS的第三方服务,或者是本文的这种情况:在内嵌的webview里访问没有HTTPS的网页~
正常的Android应用,内嵌个webview,配置一下cleartextTrafficPermitted
就可以正常访问HTTP内容了,但是flutter官方的webview组件有点坑,你在flutter项目内的Android工程配置好cleartextTrafficPermitted
之后他不管用……
每次遇到HTTP的网页,就会报这个错,很烦
然后这个问题我查了很久也没啥好的解决方案,看到有人给flutter官方提了issues,但是还没解决,那只能自己来强行解决了……
我的思路是:遇到HTTP地址,直接转成HTTPS来访问,不过这只能解决那些同时有HTTP和HTTPS的网站,遇到只有HTTP的网站就没辙啦~
强行的实现过程
实现的代码很简单,首先利用Webview的onWebViewCreated
事件获取WebViewController
实例,然后在onPageFinished
页面加载完成事件里判断当前页面地址是否http开头,如果是的话就替换成HTTPS并且重新加载即可~
因为http的页面加载在iOS上是白屏,Android上是错误信息,所以为了提高用户体验,我们可以在onPageStarted
事件里加入一个加载中的提示框。
做完的效果如下:
涉及的代码如下:
WebView(
initialUrl: _url,
allowsInlineMediaPlayback: true,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) => _webViewController = controller,
onProgress: (value) => print('page progress: $value'),
onPageStarted: (url) {
print('onPageStarted: $url');
if (url.contains('http://')) {
_httpFlag = true;
showLoading(context);
}
},
onPageFinished: (value) {
print('onPageFinished: $value');
if (value.contains('http://')) {
setState(() {
_url = value.replaceAll('http://', 'https://');
});
_webViewController.loadUrl(_url);
}
if (value.contains('https://') && _httpFlag) {
_httpFlag = false;
Navigator.of(context).pop();
}
},
),
比较蠢的解决方法,通过效果图可以看到,对用户体验的提升其实很有限,其实根本是治标不治本的,真要解决这问题还得靠官方~
真正的解决
其实前面说了这么多,真正的解决方案还是靠的flutter官方填坑,好消息是,在最新的flutter2版本中,flutter官方已经成功填坑,现在我们只需要在AndroidManifest.xml
里配置好usesCleartextTraffic
和network_security_config
即可!
具体操作就是在flutter项目下创建/android/app/src/main/res/xml/network_security_config.xml
文件,填上配置内容:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
然后修改/android/app/src/main/AndroidManifest.xml
文件,在application
节点加入以下两个属性即可:
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
完成之后你的项目结构应该是类似这样的
之后在控制台执行flutter clean
,重新run,就可以看到App里的webview能正常打开HTTP网站了,妙啊~
参考资料
How to fix 'net::ERR_CLEARTEXT_NOT_PERMITTED' in flutter:https://stackoverflow.com/questions/55592392/how-to-fix-neterr-cleartext-not-permitted-in-flutter 在 Flutter 中使用 WebView:https://zhuanlan.zhihu.com/p/77083307
往期推荐
使用Flutter设计一个好看的"我"页面
Flutter移动应用快速构建实践——状态管理、国际化、数据持久化、性能优化(二)
Flutter开发:迁移Flutter应用到AndroidX