9

我在我的应用程序的 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 值——该值来自之前的三到四次安装,这些安装之后都是卸载

我怎么可能看到这个?我如何才能真正删除应用程序的所有 cookie?

4

4 回答 4

9

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

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

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

...

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

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

这留下了一个问题:为什么有时会发送一些 cookie,即使您清除了它们onCreate?事实证明,removeAllCookie 它也是异步的——有时它会在你发出第一个请求之前完成,有时它不会,在后一种情况下,它会发送仍然处于活动状态的值:你第一次安装时仍然处于活动状态的值在持久存储中。

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

于 2012-12-22T09:36:39.433 回答
1

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

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

于 2013-06-05T14:30:43.780 回答
1
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();
}
于 2017-03-27T07:26:28.943 回答
0

试试下面的代码:

BasicHttpContext 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);
于 2012-12-22T09:28:13.120 回答