探索过程

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里配置好usesCleartextTrafficnetwork_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网站了,妙啊~

参考资料

欢迎交流

程序设计实验室专注于互联网热门新技术探索与团队敏捷开发实践,在公众号「程序设计实验室」后台回复 linux、flutter、c#、netcore、android、kotlin、java、python 等可获取相关技术文章和资料,同时有任何问题都可以在公众号后台留言~

有模有样解决Flutter里Webview无法访问HTTP页面的问题的更多相关文章

  1. 解决用户绕过Servlet直接访问jsp页面

    解决用户绕过ActionServlet,直接访问jsp文件的问题 1.将所有jsp文件拷贝到WEB-INF目录下 因为WEB-INF目录中的内容不能直接访问,但能转发过来 项目结构图如下: 2.修改s ...

  2. 解决:LNMP架构下访问php页面出现500错误

    默认情况下,如果被访问的php脚本中包含语法错误,服务器会返回一个空的“200 ok”页面 在php.ini中的fastcgi.error_header选项允许在这种情况下产生一个HTTP错误码 以使 ...

  3. 解决div里插入img下边缝隙问题

    <html>   <head>   <title> new document </title>   <meta name="author ...

  4. # 模乘(解决乘法取模爆long long)

    模乘(解决乘法取模爆long long) 二进制思想,变乘法为多次加法,具体思想跟着代码手算一遍就理解了,挺简单的 ll qmul(ll a,ll b,ll m) { ll ans=0; while( ...

  5. Android WebView组件 访问部分网页崩溃问题【已解决】

    最近刚接触Android,在测试WebView组件时发现总是出现崩溃现像: 提示:ERR_CLEARTEXT_NOT_PERMITTED 当时以为是权限问题,查找自己的AndroidManifest文 ...

  6. thinkphp从数据库里的html代码显示页面不解析

    首先,这个问题不应该出现在这里,因为以前在用ThinkPHP3.1.2的时候,利用富文本编辑器保存文本后,直接从数据库里面取出的数据都能正常显示,改用ThinkPHP3.2.3之后,thinkphp从 ...

  7. 直击根源:微信小程序中web-view再次刷新后页面需要退两次

    背景 在上一章(直击根源:vue项目微信小程序页面跳转web-view不刷新)解决了vue在小程序回退不刷新的问题之后,会引出了一个刷新的页面需要点击返回两次才能返回上一个页面 问题描述 在A页面从B ...

  8. ueditor的工具栏显示乱码解决方法 小问题.. 是你的页面编码与语言包js编码不符所导致的

    ueditor的工具栏显示乱码解决方法 小问题..  是你的页面编码与语言包js编码不符所导致的解决方法:用记事本将ueditor\..\lang\zh-cn\zh-cn.js打开,然后保存为ANSI ...

  9. 集群重启后启动ambari-server访问Web页面无法启动集群解决

    集群重启后启动ambari-server访问Web页面无法启动集群解决 使用ambari部署的集群重新启动后,必须手动重启ambari-server和所有集群主机上的ambari-agent. amb ...

随机推荐

  1. mysql.data.entityframeworkcore 已弃用

    转官网有方案: https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core.html General R ...

  2. Windows进程间通讯(IPC)----管道

    管道的分类 管道其实际就是一段共享内存,只不过Windows规定需要使用I/O的形式类访问这块共享内存,管道可以分为匿名管道和命名管道. 匿名管道就是没有名字的管道,其支持单向传输数据,如果需要双向传 ...

  3. ES6中函数参数默认值问题

    参数默认值 // 以前的参数默认值写法 let fn = (a, b) => { a = typeof a === "undefined" ? 10 : a b = type ...

  4. nginx 的常用模块

    nginx的常用模块 ngx_http_index_module Syntax: index file ...; Default: index index.html; Context: http, s ...

  5. stm32之ADC应用实例(单通道、多通道、基于DMA)-转载精华帖,最后一部分的代码是精华

    硬件:STM32F103VCT6    开发工具:Keil uVision4    下载调试工具:ARM仿真器网上资料很多,这里做一个详细的整合.(也不是很详细,但很通俗).所用的芯片内嵌3个12位的 ...

  6. HEX与ASCII之间装换

    static const char bcd_ascll[20]={0x30,0x31,0x32,0x33,0x34, 0x35,0x36,0x37,0x38,0x39,                 ...

  7. 10.7 netstat:查看网络状态

    netstat命令 用于显示本机网络的连接状态.运行端口和路由表等信息. netstat命令的参数选项及说明 -r 显示路由表信息,该功能类似于前面学过的route 和ip route-g 显示多播功 ...

  8. 关于lua闭包导致引用无法释放内存泄露

    最近项目存在严重的内存泄漏问题,每次切level 会增加20M无法释放的内存,翻遍了项目用了多个工具,查询资料等 发现项目中两种存在内存泄露的情况 1.lua闭包的不当使用,对比包的引用要及时 释放. ...

  9. 五分钟带你读懂 堆 —— heap(内含JavaScript代码实现!!)

    一.概念  说起堆,我们就想起了土堆,把土堆起来,当我们要用土的时候,首先用到最上面的土.类似地,堆其实是一种优先队列,按照某种优先级将数字"堆"起来,每次取得时候从堆顶取.  堆 ...

  10. .Net Redis实战——使用Redis构建Web应用

    示例介绍 示例1:借助Redis实现购物车功能 示例2:Redis实现网页缓存和数据缓存 借助Redis实现购物车功能 每个用户的购物车都是一个散列,散列存储了商品ID与商品订购数量之间的映射.订购商 ...