Androidh5页面
⑴ Android 微信H5支付,无法拉起微信支付页面
最近我其中一个项目需要接入微信支付,实现方式是在WebView里利用Url拉起微信支付页面,但是实际操作的时候却发现始终无法拉起支付页面,最后排查了一段时间,发现原来是因为一个很简单的问题出错了,于是解决问题以后特意想把这个问题记录下来分享,也便于以后自己解决同类问题。
可以看到,这里return 返回的是false,问题出在这里。这时我又在想,为什么会这样?
查阅资料以后我发现shouldOverrideUrlLoading的返回值的意义为:
那么这种情况下,返回值应该改为 false或者super .shouldOverrideUrlLoading(view, url); ,因为微信支付调用 https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb 这个开头的url后,会重定向到 weixin://wap/pay 开头的url,然后调用微信客户端支付,如果用true,则WebView不会自动重定向到 weixin://wap/pay 开头的url,需要程序员自行处理,这种情况下自然是无法吊起支付的。
⑵ Android h5页面token失效(记录项目的一个bug)
在做项目的时候,需要在原生页面集成H5页面,本地WebView会储存网页的橘余cookie。
cookie中会存入一些用户信息和token。
这个token是有时效性,并且请求服务端的时候,服务端会进行token校验。H5在加载的时候会将token写入cookie中,并将cookie写入对应的域(domain)名中。但是项目的圆汪滚域名改过,却没有将原先的cookie清除,导致又写入新的cookie。再请求服务端的时候将根路径下的cookie全上传给服务端了,服务端根据cookie中的token别名去取 token(默认第一个),但是这个排序又是无序的。导致有时陵早会拿到错误的token。即返回登录状态失效,直接退出了。
截图如下:
⑶ android开发中,webview常用于显示网页或h5页面,一个遇到跨域方面的坑。
1.跨域cookie读取
什么是跨域,简单的说就是不同的域名,我们都知道在pc上我们用浏览器访问网址,不同的网址都会在本地存储一些cookie信息,这样就可以实现比如自动登录等功能,在pc上不同域名是不能相互读取其他域下的cookie信息的(非web专业开发人员,如果理解有误,欢迎指出)。
但是在 android 上在api 23之前,是可以跨域读取cookie的,比如A域写入一个userId的cookie,B域可以读取该值。但是在23时,系统将该值设置成了false,不再让跨域读取了。如果你的应用有跨域读取需求,怎么办?可以采用如下方式进行开启:
/*** 设置跨域cookie读取*/
public final void setAcceptThirdPartyCookies() {
//target 23 default false, so manual set true
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { CookieManager.getInstance().setAcceptThirdPartyCookies(webView,true);
}
}
2.http/https混合加载
在现阶段,很多网站都改成了https进行访问,https可以提升访问网站的安全性,防止信息被窃取,如果所有的网页都是https且网页内的链接也是都是https,那就没有混合加载(文本区域https,图片文件http加载)的问题了。但是很多资源现阶段还没有改变成https访问,往往页面都嵌入了http的链接。这种混合网页如果不进行处理,直接加载是会出现错误的。怎么解决这个问题?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
这也是一个分版本的函数,在api23之前,默认是可以混合加载的,但是在23时,默认值改成了MIXED_CONTENT_NEVER_ALLOW,因此如果你有混合加载的需求,设置setMixedContentMode为MIXED_CONTENT_ALWAYS_ALLOW。
3.无法解决跨域访问问题,可以尝试给webview设置如下配置,已解决该问题;
if (Build.VERSION.SDK_INT >= 16) {
Class clazz =webView.getSettings().getClass();
Method method = clazz.getMethod("", boolean.class);
if (method != null) {
method.invoke(webView.getSettings(), true);
}
}
} catch (IllegalArgumentExceptione) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}