Contents
  1. 1. 配置HTTPs
    1. 1.1. WebViewClient
    2. 1.2. WebView的Setting
    3. 1.3. 示例程序
  2. 2. 加载淘宝客链接

越来越多的Web页面采用了更为安全的HTTPs方式,移动端的同样。虽然Apple早先宣布的2017年1月1日全面执行HTTPs的策略被推迟了,但是该来的还是要来的,我相信未来越来越多的页面会采用HTTPs的方式。而Android的WebView在加载HTTPs页面时,如果不经过一些设置,可能出现页面不能加载,或者页面上的某些资源显示不出来等问题。
本篇文章就来看一看如何才能正确地加载Https页面。同时,对于淘宝客的链接(s.click.taobao.com),这里也来记录下如果才能正确显示。

配置HTTPs

正确配置HTTPs需要设置两个地方:重写WebViewClient的OnReceiveSslError方法,以及WebView的settings

WebViewClient

很多HTTPs页面加载不出来的主要原因是SSL证书不能被正确识别,所以我们这里要做的,就是重载WebViewClient中的OnReceiveSslError方法:

1
2
3
4
5
6
7
8
/**
* Description: handle https
* Created by Michael Lee on 12/6/16 08:38
*/
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
}

这样,当收到证书错误时,忽略掉,直接继续处理就行了;相当于信任了所有的证书一样。

WebView的Setting

另外加载HTTPs页面还有一个常见的问题就是页面中某些资源(例如图片)加载不出来。这个原因是页面使用了HTTPs和HTTP混合的方式。就是说虽然当前的页面是通过HTTPs方式传输的,但是页面里的某些图片,确实使用类似<img src='http://www...'>的方式加载不是HTTPs的资源,这个时候,如果不对我们的WebView做设定,默认也是无法加载的。

注:
Android的这个安全策略尽在SDK 22,也就是LOLLIPOP版本之后才启用,之前的版本是没有做这个策略控制的。

1
2
3
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}

示例程序

其实就是这两个地方经过配置以后,我们的WebView就可以正常显示HTTPs页面了,我们来看个完整的示例程序吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 省略各种无关代码...

// new一个webview对象
WebView web_view = new WebView();
// 设置允许加载混合内容
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
web_view.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}

// 允许所有SSL证书
web_view.setWebViewClient(new WebViewClient() {
/**
* Description: handle https
* Created by Michael Lee on 12/6/16 08:38
*/
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
}
});

// 试着加载一个HTTPs的页面
web_view.load("https://www.google.com");

加载淘宝客链接

什么是淘宝客链接?就是淘宝的推广链接;大概意思就是:
如果你的淘宝店面要推广,那你可能让你的小伙伴A、B、C和D都来帮你宣传,那你要给他们每个人分配一个不同的URL,这些URL最后都将跳转到你的淘宝店面,但是他们每个人的链接是不一样的,这样你就可以统计到底有多少人是通过点击他们的链接来到你的店面的,你就可以决定请谁吃顿大餐或者请谁喝瓶饮料就够了。。。
之前在项目中发现,WebView不能正确地进行跳转,有时候是空白页面,有时候会跳到淘宝的首页去。其实网上也能搜到答案,就是显式调用WebViewClient的onPageStart方法

但是对于很多需要修改WebView的APP来说,我们已经重写了WebViewClient的shouldOverrideUrlLoadingonPageStart以及onPageFinish方法了,那如何是好呢??
其实方法也不难,就是每次先去判断下当前的URL是不是一个推广链接,如果是一个推广链接,则不做任何处理;否则的话,就按照我们自己的逻辑处理就ok了。

我们继续在上面的示例代码中进行补充:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// 省略各种无关代码...

// new一个webview对象
WebView web_view = new WebView();
// 设置允许加载混合内容
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
web_view.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
// 允许所有SSL证书
web_view.setWebViewClient(new WebViewClient() {
/**
* Description: handle https
* Created by Michael Lee on 12/6/16 08:38
*/
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
}

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
String decoded_url = url;
try {
decoded_url = URLDecoder.decode(url, "UTF-8");
Log.d("WebView", "shouldOverrideUrlLoading's url is :" + decoded_url);
} catch (Exception e) {
Log.e("WebView","Catch error when decoding. Error message : " + e);
}

if (!checkUrlValid(decoded_url)) {
super.shouldOverrideUrlLoading(view,url);
Log.d("WebView","Handle url with system~~");
return false;
} else {
// Do your special things
return true;
}
}

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.d("WebView", "onPageStarted : " + url);
if (!checkUrlValid(url)) {
super.onPageStarted(view,url,favicon);
Log.d("WebView","Handle url with system~~");
return;
} else {
// Do your special things
}
}

@Override
public void onPageFinished(WebView view, String url) {
Log.d("WebView","onPageFinished : " + url);
if (!checkUrlValid(url)) {
super.onPageFinished(view,url);
Log.d("WebView","Handle url with system~~");
return;
} else {
// Do your special things
}
}
});

// 试着加载一个HTTPs的页面
web_view.load("https://www.google.com");

我们可以用下面的方法来判断URL是不是一个推广链接。
我这里的判断比较简单,仅仅判断URL里面有没有包含s.click,严谨的写法应该是尽可能多地包含进来更多的推广链接地址,例如s.click.taobao, 或者s.click.tmall 或者其他url的推广地址。因为我这里的写法如果恰巧一个URL里面就包含了s.click可能会导致页面没有按照你自己的逻辑来处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Description: check if the url is valid, such as taobao's url like this "https://s.click.tao"
* or "s.click.tmall.com", can not modify the onPageStart method
* Created by Michael Lee on 12/30/16 16:08
* @param aUrl webview's url
* @return true if url is NOT contains "s.click"
*/
private boolean checkUrlValid(String aUrl) {
boolean result = true;
if (aUrl == null || aUrl.equals("") || !aUrl.contains("http")) {
return false;
}
if (aUrl.contains("s.click")) {
result = false;
}
return result;
}

这样处理之后,你的WebView应该就能正确加载大部分的Https页面了。

Contents
  1. 1. 配置HTTPs
    1. 1.1. WebViewClient
    2. 1.2. WebView的Setting
    3. 1.3. 示例程序
  2. 2. 加载淘宝客链接