先说问题:
年会H5cooki同步失败。但是
- 如果重新下载安装,成功
- 旧app,进入app后,不先进入年会H5,首先进入其他H5界面,再回过来进入年会H5,成功
事情缘由:
2022准备开年会了,行政方面,想通过内部OA系统,进行一轮企业文化的答题环节。答题环节的内容是H5,App端,只需一个WebView load就行。公司的OA,历经不下10人的版本迭代、代码风格参差不齐,好不容易找到加载的地方---一个名叫H5ActivityActivity的类。
问题分析:
1.本地的Cookie是肯定存在的,问题一定出现在同步cookie进webView的地方。
2.如果是如1所说,为什么是偶发性呢?
3.为什么卸载、重装就恢复了呢?
代码部分:
CookieSpUtil.syncCookie(this, "");//同步cookie
final WebView mWebView = (WebView) findViewById(R.id.mWebView);
if(TextUtils.isEmpty(webUrl))
return;
mWebView.loadUrl(webUrl);
WebSettings settings = mWebView.getSettings();
.....
/**
* 同步cookie,准备显示网页
*/
public static void syncCookie(Context context,String defValue){
String cookie = CookieSpUtil.getCookieString(context,defValue);
String[] cookies = cookie.split(";");//这里一定是有值的
CookieManager cookieManager = CookieManager.getInstance();
for (int i = 0;i < cookies.length;i++){
cookieManager.setCookie(Constant.root, cookies[i]);//这里设置
}
CookieSyncManager cookieSyncManager = CookieSyncManager.createInstance(context);
cookieSyncManager.sync();//同步
}
第一次bug定位:setCookie(如果,domain错误,那肯定是同步失败的)
在setCookie时,第一个参数是传入的domain,和前端哥们综合会诊后,发现历史代码中domain是一个三级域名,例如:fat1.fat2.fat3,而年会H5的三级域名为:h5.fat2.fat3。因为域名是一级含二级,二级含三级,所以这里是有问题的,于是修改domain为二级域名。
第二个疑问?为什么进入别的H5界面,再回来,就好了?按道理,既然domain错误,那是100%同步失败的啊
CookieSpUtil.syncCookie(this, "");//同步cookie
final WebView mWebView = (WebView) findViewById(R.id.mWebView);
if(TextUtils.isEmpty(webUrl))
return;
mWebView.loadUrl(webUrl);
WebSettings settings = mWebView.getSettings();
.....
又和前端哥们、后端哥们综合会诊,发现,因为其他H5的domain都是fat1.fat2.fat3,what?为什么不做成一样的呢?
这就没事了,先进入一个其他H5,cookie会同步成功,再进入年会H5时,同步cookie失败。但是,因为之前的cookie,所以可以正常进入。
第三个疑问?为什么卸载、重装后,就恢复了呢?
经排查,发现,卸载、重装后,进入app主界面,第一时间,会弹出一个VersionInfo的H5界面,其原理和第二个疑问一样,
这样,一切都通了。
而后,把同步问题,还做了些适配
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.flush();
} else {
CookieSyncManager.getInstance().sync();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0以上,WebView默认不允许跨域获取cookie
CookieManager.getInstance().setAcceptThirdPartyCookies(mWebView, true);
}
最后,为了保证年会能顺利的进行下去,还做了一个临时的兜底方案,把用户名当参数拼接到url里,这样,就万无一失了。
至于这个在线上,且经历了数代的代码,改一处,动全身,
想要重构,可能需要提上公司层面,前后端配合,才能进行了。
暂时,只能从App端,一处一处优化。