【问题标题】:CookieManager.getInstance().removeAllCookie(); doesn't remove all cookiesCookieManager.getInstance().removeAllCookie();不会删除所有 cookie
【发布时间】:2012-12-15 23:03:39
【问题描述】:

我在我的应用程序的 onCreate 中调用 CookieManager.getInstance().removeAllCookie()。

我遇到了一个奇怪的问题,我看到一个意外的 cookie 值在 GET 请求中被传递。事实上,cookie 值是一个非常非常古老的值。

以下是我为测试执行的步骤:

  1. 安装应用程序
  2. 在应用启动时发出 GET 请求。请求应该是干净的:不应该发送任何 cookie。
  3. GET 请求以 Set-Cookie 响应。该值基于请求时间,因此该值在任何两个请求上相同的可能性非常小。
  4. 发出另一个 GET 请求。请求应从第 3 步发送 cookie 值。

我第一次安装应用程序时,cookie 的行为与我预期的一样。我卸载了该应用程序,然后重新安装它,cookie 行为再次按预期工作。我这样做了几次,一切都很好。

然后,突然,在第 N 次安装时,第 2 步没有通过。第一个 GET 请求不干净。事实上,它带有一个在首次安装应用时设置的值。

我无法可靠地重现此问题,但我确实经常看到它。这并不是说安装时的第一个 GET 请求是从上一次安装中发送一个 cookie 值——该值来自之前的三到四次安装,这些安装之后都是 uninstalls

我怎么可能看到这个?我如何实际上删除应用程序的所有 cookie?

【问题讨论】:

    标签: android cookies


    【解决方案1】:

    这是在黑暗中拍摄的,但也许您第一次安装的 cookie 保存在持久存储中,而重新安装的 cookie 缓存在 RAM 中。也许出于某种原因,删除所有 cookie 的操作没有同步到持久存储,因此它在重新安装之间保留旧值。

    引用CookieSyncManager 的文档(强调我的):

    CookieSyncManager 用于在 RAM 和永久存储之间同步浏览器 cookie 存储。为了获得最佳性能,浏览器 cookie 保存在 RAM 中。 单独的线程保存它们之间的 cookie,由计时器驱动

    ...

    同步间隔为 5 分钟,因此无论如何您都需要手动强制同步,例如在 onPageFinished(WebView, String) 中。请注意,即使 sync() 发生异步,所以不要在你的活动正在关闭时这样做

    这强烈表明可能(在您的测试中,我假设有时在不到 5 分钟的时间间隔内进行)当应用程序被卸载时它还没有同步,所以第一次安装的旧值是此时仍在持久存储中。我也没有理由假设如果没有超过 5 分钟的间隔,卸载期间会发生同步。

    这就留下了一个问题:为什么有时会发送一些 cookie,即使您在 onCreate 中清除了它们?原来removeAllCookieis also asynchronous - 有时它会在你发出第一个请求之前完成,有时它不会,在后一种情况下它会发送仍然有效的值:你第一次安装的值,仍在持久存储中。

    (请注意,我仍在学习 Android 开发,我的一些假设可能是错误的——关于如何管理 cookie 以及在 activity's lifecycle 中的一种状态下进行的异步调用是否可能仍未完成当另一个运行时;但这种解释与您描述的行为非常一致)

    【讨论】:

      【解决方案2】:

      请在 CookieManager.getInstance().removeAllCookie() 调用后立即调用 CookieSyncManager.getInstance().sync()。

      原因正如@mgibsonbr 所述,一个单独的线程保存cookies,由一个计时器驱动,以便使其持久化,立即显式调用CookieSyncManager.getInstance().sync()。

      【讨论】:

        【解决方案3】:
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                CookieManager.getInstance().removeAllCookies(null);
            } else {
        
                CookieSyncManager.createInstance(context);
                CookieManager cookieManager = CookieManager.getInstance();
                if (cookieManager != null) {
                    cookieManager.removeAllCookie();
                }
         CookieSyncManager.getInstance().sync();
        }
        

        【讨论】:

        【解决方案4】:

        试试下面的代码:

        基本HttpContext mHttpContext;

        CookieStore mCookieStore;
        String persistentcookie;
        CookieManager cookieManager;
        CookieSyncManager syncManager;
        private MultipartEntity m_hsmpeMultipartReqEntity;
        
          //manages the session of the webview for the image uploading on the server.
        syncManager = CookieSyncManager.createInstance(m_hswvWebView.getContext());
        syncManager.startSync();
        cookieManager = CookieManager.getInstance();
        boolean cok=cookieManager.acceptCookie(); // Here your cookie
        persistentcookie=cookieManager.getCookie("http://www.xxxx.com/");       
        String[] splitstr=pat.split(persistentcookie.toString());
        String key=splitstr[0]; // Key of the Cookie
        String value=splitstr[1]; //Session id
         m_hshttpClient = new DefaultHttpClient();
         mHttpContext  = new BasicHttpContext();
         mCookieStore = m_hshttpClient.getCookieStore();        
        
         BasicClientCookie clientcookie=new BasicClientCookie(key,value);
         clientcookie.setDomain(“www.xxxx.com”); // set the proper Domain URL
         mCookieStore.addCookie(clientcookie);             
         m_hshttppostRequest = new HttpPost(“http://www.xxxx.com/");
         // post URL after setting               cookie value.
        
         //set the cookie attribute in the BasicHTTPContext.
        
        mHttpContext.setAttribute(ClientContext.COOKIE_STORE, mCookieStore);
        m_hsmpeMultipartReqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
        
        m_hshttppostRequest.setEntity (m_hsmpeMultipartReqEntity);
        m_hshttpResponse = m_hshttpClient.execute(m_hshttppostRequest,mHttpContext);
        

        【讨论】:

          猜你喜欢
          • 2018-06-20
          • 1970-01-01
          • 2018-12-02
          • 2020-12-27
          • 2012-09-10
          • 1970-01-01
          • 2011-01-18
          • 1970-01-01
          • 2020-09-29
          相关资源
          最近更新 更多