解决android 5.0 webview不能加载http与https混合内容的问题
在使用WebView加载https资源文件时,如果认证证书不被Android认可,那么会出现无法成功加载对应资源问题。那么,我们就要针对这一状况作出对应的处理。
1、解决方法:启用mixed content ,webview默认不允许加载http与https混合内容:
比如你访问的网页为http://xxx.com/a.html,则如果a.html包含了https的资源,则此资源不会显示。如果仔细观察log,可以看到如下的内容提示:
********was loaded over HTTPS, but requested an insecure image********
该怎么解决呢?很简单,只需设置webSettings,允许其加载混合网络协议内容即可。
1 //webview在安卓5.0之前默认允许其加载混合网络协议内容 2 // 在安卓5.0之后,默认不允许加载http与https混合内容,需要设置webview允许其加载混合网络协议内容 3 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 4 settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); 5 }
从Android5.0以后,当一个安全的站点(https)去加载一个非安全的站点(http)时,需要配置Webview加载内容的混合模式,一共有如下三种模式:
- MIXED_CONTENT_NEVER_ALLOW:Webview不允许一个安全的站点(https)去加载非安全的站点内容(http),比如,https网页内容的图片是http链接。强烈建议App使用这种模式,因为这样更安全。
- MIXED_CONTENT_ALWAYS_ALLOW:在这种模式下,WebView是可以在一个安全的站点(Https)里加载非安全的站点内容(Http),这是WebView最不安全的操作模式,尽可能地不要使用这种模式。
- MIXED_CONTENT_COMPATIBILITY_MODE:在这种模式下,当涉及到混合式内容时,WebView会尝试去兼容最新Web浏览器的风格。一些不安全的内容(Http)能被加载到一个安全的站点上(Https),而其他类型的内容将会被阻塞。这些内容的类型是被允许加载还是被阻塞可能会随着版本的不同而改变,并没有明确的定义。这种模式主要用于在App里面不能控制内容的渲染,但是又希望在一个安全的环境下运行。
2、解决方法:设置WebView接受所有网站的证书
在认证证书不被Android所接受的情况下,我们可以通过设置重写WebViewClient的onReceivedSslError方法在其中设置接受所有网站的证书来解决,具体代码如下:
1 webView.setWebViewClient(new WebViewClient() { 2 @Override 3 public void onReceivedSslError(WebView view, 4 SslErrorHandler handler, SslError error) { 5 // TODO Auto-generated method stub 6 // handler.cancel();// Android默认的处理方式 7 handler.proceed();// 接受所有网站的证书 8 // handleMessage(Message msg);// 进行其他处理 9 } 10 });
注:在重写WebViewClient的onReceivedSslError方法时,注意一定要去除onReceivedSslError方法的super.onReceivedSslError(view, handler, error);,否则设置无效。
熊猫办公https://www.wode007.com/sites/73654.html
解决浏览器默认是不允许在 https 里面引用 http 资源
浏览器默认是不允许在 https 里面引用 http 资源的,一般都会弹出提示框。
用户确认后才会继续加载,用户体验非常差。而且如果在一个 https 页面里动态的引入 http 资源,比如引入一个 js 文件,会被直接 block 掉的。Chrome v21 之后,在 SSL 加密页面 embed 非 SSL 的 Flash 资源也会被默默的屏蔽掉,只留下一句 console 报告。
1、解决方法:让网站同时准备了 https 资源和 http 资源,通过相对协议的形式访问:
<img src="//domain.com/img/logo.png">
简而言之,就是将URL的协议(http、https)去掉,只保留//及后面的内容。这样,在使用https的网站中,浏览器会通过https请求URL,否则就通过https发送请求。
附注:如果是浏览本地文件,浏览器通过file://协议发送请求,导致请求失败,因此本地测试最好是搭建一个本地服务器。
2、解决方法:将http请求转成https请求,添加响应头,设置mate如下:
<meta http-equiv='Content-Security-Policy' content='block-all-mixed-content'>
或者在我们服务器响应头中加入:
header("Content-Security-Policy: upgrade-insecure-requests");
我们的页面是 https 的,而这个页面中包含了大量的 http 资源(图片、iframe等),页面一旦发现存在上述响应头,会在加载 http 资源时自动替换成 https 请求。