cookie加载不正确的问题

本文介绍了一次系统更新后导致Android应用中H5页面登录失败的问题排查与修复过程。问题源于系统更新后Cookie同步机制的变化,导致Cookie未能正确传递。通过调整代码逻辑,将异步操作正确处理,最终解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

华为系统更新后安装了一个谷歌6月安全补丁的东西,然后之前写的调h5页面的部分就出现了问题,后台查过发现是Android端调h5页面时cookie没能带过去,导致了登录失败。于是对setCookie部分的代码进行了调试,发现单步运行时只要在setCookie部分时多等一会页面就可以正常打开,所以怀疑是异步的问题,先是在网上查了一通,说是这种情况可以让程序多睡会,但是这种解决方法并没有成功,而且觉得这么写代码有点别扭,于是就又查了一下设置Cookie部分的官方说明,发现 cookieManager.removeAllCookies其实是异步函数,之前写代码的人把他当同步用了,导致setCookie完成后,removeAllCookies函数才执行完的,把填进去的cookie又给移除了,所以导致了打开页面的失败。没安补丁之前,可能是cookie都带过去了,remove函数才执行完,安补丁后remov函数的运行速度提升了,但是具体原因不明,因为查不到补丁的内容,总之无论如何,异步函数当同步使用是万万不能的。

以下是改之前错误的代码,removeAllCookies被当成了同步函数使用

   void fun(){
        ...
        addCookies();
        mWebview = (SystemWebView) appView.getView();
        engine = (SystemWebViewEngine) appView.getEngine();
        mWebview.setWebViewClient(new SystemWebViewClient(engine){
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

           ...
        });
    }


    private void addCookies() {
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.removeAllCookie();
        cookieManager.setAcceptCookie(true);
        List<Cookie> cookieList = MainApp.getInstance().getGlobalState().getCookies();
        for (Cookie cookie: cookieList){
            String cookieString = cookie.name() + "=" + cookie.value();
            cookieManager.setCookie(url, cookieString);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            cookieManager.flush();
        } else {
            CookieSyncManager.createInstance(this);
            CookieSyncManager.getInstance().sync();
        }
    }

以下是改后的代码,removeAllCookies()有一个完成后会在当前线程调用的方法,利用他remove完成后在set就没问题了,而且addCookie()的调用被移进了onPageStarted之前,不然,之前那么写的话会先完成调用onPageStarted(),后完成addCookie()的调用,cookie依然不能设置成功。addCookie()不能放在onPageStarted中,应该加载完cookie再加载url,在loadUrl之前调用

 void fun(){
        mWebview = (SystemWebView) appView.getView();
        engine = (SystemWebViewEngine) appView.getEngine();
        mWebview.setWebViewClient(new SystemWebViewClient(engine){
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
              //  addCookies();
                super.onPageStarted(view, url, favicon);
            }

           ...
        });

  }


    private void addCookies() {
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            cookieManager.removeAllCookies(new ValueCallback<Boolean>() {
                @Override
                public void onReceiveValue(Boolean value) {
                    setCookie(cookieManager);
                }
            });
        }else{
            cookieManager.removeAllCookie();
            setCookie(cookieManager);
        }
    }

    void setCookie( CookieManager cookieManager){

        List<Cookie> cookieList = MainApp.getInstance().getGlobalState().getCookies();
        for (Cookie cookie: cookieList){
            String cookieString = cookie.name() + "=" + cookie.value();
            cookieManager.setCookie(url, cookieString);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            cookieManager.flush();
        } else {
            CookieSyncManager.createInstance(this);
            CookieSyncManager.getInstance().sync();
        }

        loadUrl();
    }

 这是removeAllCookies()方法的完整说明

/**
 * Removes all cookies.
 * <p>
 * This method is asynchronous.
 * If a {@link ValueCallback} is provided,
 * {@link ValueCallback#onReceiveValue(T) onReceiveValue()} will be called on the current
 * thread's {@link android.os.Looper} once the operation is complete.
 * The value provided to the callback indicates whether any cookies were removed.
 * You can pass {@code null} as the callback if you don't need to know when the operation
 * completes or whether any cookies were removed, and in this case it is safe to call the
 * method from a thread without a Looper.
 * @param callback a callback which is executed when the cookies have been removed
 */
public abstract void removeAllCookies(ValueCallback<Boolean> callback);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值