关于WebView的同步cookie

先说问题:

年会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端,一处一处优化。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容