Android WebView Cookie獲取和設(shè)置,原生和H5同步token實(shí)現(xiàn)邏輯

轉(zhuǎn)載請(qǐng)注明原創(chuàng)出處,謝謝!

ps:
當(dāng)我們實(shí)現(xiàn)原生app使用webView打開網(wǎng)頁(yè)時(shí)候,然后h5網(wǎng)頁(yè)有登錄邏輯,會(huì)自動(dòng)跳轉(zhuǎn)到H5頁(yè)面的登錄頁(yè),但當(dāng)用戶已經(jīng)在我們app登錄過(guò),這時(shí)候再讓用戶進(jìn)行一次登錄操作,是非常不友好的用戶體驗(yàn)。

例如一個(gè)非常實(shí)現(xiàn)的業(yè)務(wù),用戶在打開app后會(huì)有一個(gè)活動(dòng)彈窗,點(diǎn)擊彈窗進(jìn)入H5的活動(dòng)落地頁(yè),但是活動(dòng)這種業(yè)務(wù)需求,生命周期是非常短的,運(yùn)營(yíng)同學(xué)可能幾天就換一種運(yùn)營(yíng)方式,抽獎(jiǎng)、送優(yōu)惠券、積分兌換等,實(shí)現(xiàn)邏輯不同,頁(yè)面風(fēng)格也不同,這種時(shí)候,如果我們的app一直頻繁的發(fā)版,升級(jí)app版本是非常不友好的用戶體驗(yàn)。而這種活動(dòng)落地頁(yè)面,始終伴隨著用戶信息,需要用戶登錄狀態(tài)才可以正常參與。

這時(shí)候記錄用戶登錄信息,下次打開H5頁(yè)面,不需要重復(fù)登錄這個(gè)需求,就十分重要了?。。?/h4>

通常H5網(wǎng)頁(yè)會(huì)從Cookie獲取token,然后通過(guò)token來(lái)判斷用戶是否登錄,所以如果我們可以將app的token傳給H5,那就完美解決了問題。

實(shí)現(xiàn)方法有很多種,例如通過(guò)JS交互就可以,但是對(duì)于前端同學(xué)來(lái)說(shuō),這個(gè)改動(dòng)的工程量非常大。所以這里我是推薦使用通過(guò)設(shè)置Cookie的方式實(shí)現(xiàn),理論上前端同學(xué)是幾乎不許要?jiǎng)尤魏未a的。

下面是給網(wǎng)頁(yè)設(shè)置一個(gè)aaa=123456的cookie的例子

        // 保留cookies,而不是在隨后的重新啟動(dòng)后清除
        CookieManager cookieManager = CookieManager.getInstance();
        // 允許接受 Cookie
        cookieManager.setAcceptCookie(true);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            // 跨域cookie讀取
            cookieManager.setAcceptThirdPartyCookies(wv, true);
        }
        // 一定要給主域設(shè)置cookie,給子級(jí)地址設(shè)置,父級(jí)會(huì)無(wú)法獲取到cookie值
        Log.i(TAG, "afterLoadLayout1: "+CookieManager.getInstance().getCookie("http://192.168.7.104:8080/"));
        Log.i(TAG, "afterLoadLayout2: "+CookieManager.getInstance().getCookie("http://192.168.7.104:8080/abc"));
        Log.i(TAG, "afterLoadLayout2: "+CookieManager.getInstance().getCookie("http://192.168.7.104:8080/abc/abc"));
        cookieManager.setCookie("http://192.168.7.104:8080/", "aaa=123456");
        // cookieManager.setCookie("http://192.168.7.104:8080/abc/abc", "aaa=123456");
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            CookieSyncManager.getInstance().sync();
        } else {
            cookieManager.flush();
        }
        Log.i(TAG, "afterLoadLayoutA: "+CookieManager.getInstance().getCookie("http://192.168.7.104:8080/"));
        Log.i(TAG, "afterLoadLayoutB: "+CookieManager.getInstance().getCookie("http://192.168.7.104:8080/abc"));
        Log.i(TAG, "afterLoadLayoutB: "+CookieManager.getInstance().getCookie("http://192.168.7.104:8080/abc/abc"));
        // 配置 WebView
        WebSettings webSettings = wv.getSettings();
        // 開啟DOM storage API 功能
        webSettings.setDomStorageEnabled(true);
        // 開啟database storage API功能
        webSettings.setDatabaseEnabled(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setUseWideViewPort(true);
        webSettings.setBlockNetworkImage(false);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);

注意

  • WebSettings.setDomStorageEnabled(true); 前端網(wǎng)頁(yè)才可以拿到值。


    H5代碼.png
  • 一定要給主域設(shè)置cookie,給子級(jí)地址設(shè)置,父級(jí)地址會(huì)無(wú)法獲取到cookie值
    例如我給http://www.xx.com/設(shè)置了cookie,也就是代碼里的“aaa=123456”,http://www.xx.com/abchttp://www.xx.com/abc/abc是可以獲取到的。
    但是我們給http://www.xx.com/abc/abc,這時(shí)候http://www.xx.com/abchttp://www.xx.com/沒有辦法獲取到。
    (這個(gè)是我測(cè)出來(lái)的,我還沒看懂底層的實(shí)現(xiàn)邏輯,為什么會(huì)出現(xiàn)這種情況,所以建議直接截取url的第一個(gè)斜杠就可以,我猜是path的原因)

  • 設(shè)置cookie后,可以在View->Tool Windows->Device File Explorer,找到dada/dada/包名/app_webview/Default/Cookies里找到(這是一個(gè)SQLite3文件,使用Navicat工具就可以打開)

使用Navicat打開Cookies表.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容