zoukankan      html  css  js  c++  java
  • 有模有样解决Flutter里Webview无法访问HTTP页面的问题

    探索过程

    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 等可获取相关技术文章和资料,同时有任何问题都可以在公众号后台留言~

    It never rains but it pours. 欢迎关注我的公众号:DealiAxy 提供更多技术文章
  • 相关阅读:
    《浅谈12306核心模型设计思路和架构设计》阅读笔记
    《一路打怪升级,360推荐系统架构演进》阅读笔记
    SOA架构设计的案例分析
    《苏宁易购:商品详情系统架构设计》阅读笔记
    《数据蜂巢架构演进之路》阅读笔记
    洛谷P1005 矩阵取数游戏
    LOJ#6277. 数列分块入门 1
    洛谷P1879 [USACO06NOV]玉米田Corn Fields
    洛谷P1072 Hankson 的趣味题
    洛谷P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
  • 原文地址:https://www.cnblogs.com/deali/p/14920907.html
Copyright © 2011-2022 走看看