当前位置: 移动技术网 > IT编程>移动开发>Android > Android实现清除单个域名的cookie

Android实现清除单个域名的cookie

2020年05月11日  | 移动技术网IT编程  | 我要评论

飞机票网上订票官网 12306,面包机的使用方法,裴新华简历

今天pm提了个需求:用户退出当前网页时,只清除该网页访问的域名相关的cookie,保留其他域名的cookie。

查了一下cookiemanager的api,发现只有removeallcookie(),没有清除单独域名cookie的api。。。想想也是,用了这么多年的浏览器,啥时候见过这功能?

既然系统没有提供接口,那就是只能自己想办法去清了。

首先要搞清楚cookie存在哪里吧?

在/data/data/<package>/app_webview目录下,找到一个cookies文件,虽然它没有.db扩展名,但是其实它就是一个sqlite数据库!进去看一下,数据都存在里面的cookies表里:

sqlite> .tables
cookies meta  
sqlite> .dump cookies
pragma foreign_keys=off;
begin transaction;
create table cookies (creation_utc integer not null unique primary key,host_key text not null,name text not null,value text not null,path text not null,expires_utc integer not null,secure integer not null,httponly integer not null,last_access_utc integer not null, has_expires integer not null default 1, persistent integer not null default 1,priority integer not null default 1,encrypted_value blob default '',firstpartyonly integer not null default 0);
insert into "cookies" values(13122904895970126,'.','hmaccount','1e0666871dc4bb45','/',13792186776970126,0,0,13122906283432123,1,1,1,x'',0);
insert into "cookies" values(13122905170226445,'.facebook.com','reg_fb_ref','https%3a%2f%2fm.facebook.com%2f%3frefsrc%3dhttps%253a%252f%252fwww.facebook.com%252f','/',0,0,1,13122905170226445,0,0,1,x'',0);
insert into "cookies" values(13122905170227182,'.facebook.com','reg_fb_gate','https%3a%2f%2fm.facebook.com%2f%3frefsrc%3dhttps%253a%252f%252fwww.facebook.com%252f','/',0,0,1,13122905170227182,0,0,1,x'',0);
insert into "cookies" values(13122905170227393,'.facebook.com','m_ts','1478103992','/',0,0,0,13122905170227393,0,0,1,x'',0);
insert into "cookies" values(13122905172258460,'.facebook.com','datr','uxmawfe4eaqp6w2_ddu2mpa1','/',13185977172258460,0,1,13122905172258460,1,1,1,x'',0);
insert into "cookies" values(13122905172508865,'.facebook.com','fr','0ehmpmxi6717eje6y..bygho4.dd.aaa.0.0.bygho7.awufjmmy','/',13130681172508865,0,1,13122905172508865,1,1,1,x'',0);
create index domain on cookies(host_key);
create index is_transient on cookies(persistent) where persistent != 1;
commit;

这里面存储的其实就是http头里的set-cookie字段包含的所有信息,以facebook为例,拼起来其实就是:

set-cookie: m_ts=1478103992; datr=uxmawfe4eaqp6w2_ddu2mpa1; fr=oehmpmxi6717eje6y; path=/; domain=.facebook.com

只要我们把这些信息清除掉,webview下次发请求的时候就没有有效cookie了。最直接的想法,调用cookiemanager的setcookie()方法,把这些字段清空或者设置为过期不就行了?在stackoverflow上搜了一下,找到一个帖子讨论类似的思想,试了一下发现还是不行。。。

原文链接:

下面说一说遇到的一堆坑吧:

1. 同一个域名,http跟https两种情况下cookie带的参数是不一样的。举个例子,http://www.facebook.com跟https://www.facebook.com,通过cookiemanager.getcookie()获取 的参数是完全不一样的。这个问题困扰了我一个多小时,因为我发现有些参数死活清不掉。。。

2. cookies表里有一堆以“.”开头的域名,比如表里的那个“.facebook.com”,它的一些参数用完全域名删不掉。比如针对http://www.facebook.com调用cookiemanager.setcookie()清除字段信息,你会发现表里多了一项"www.facebook.com"的记录,而原来的".facebook.com"的记录仍然存在而且字段信息没有被清除。

3. 使用以“.”开头的域名,比如".facebook.com",调用cookiemanager.getcookie()时获取不到全的参数列表。

4. 不同的网站会在cookies表里增加多项记录,以facebook为例,表里可能会存"www.facebook.com"、".www.facebook.com"、".facebook.com"这3种记录。

最后说结论吧,几经周折,总算找到一个能用的方法,亲测5.1 / 6.0平台可用。其实也很简单粗暴,就是把上面第4条提到的那几种记录统统撸一遍,宁可错杀一千,也不放过一个。。。

附上代码(注意domain参数是带上协议的全域名,比如https://www.baidu.com):

private static void deletecookiesfordomain(context context, string domain) {
    cookiemanager cookiemanager = cookiemanager.getinstance();
    if (cookiemanager == null) return;
 
    /* http://code.google.com/p/android/issues/detail?id=19294 */
    if (build.version.sdk_int < 11) {
      /* trim leading '.'s */
      if (domain.startswith(".")) domain = domain.substring(1);
    }
 
    string cookieglob = cookiemanager.getcookie(domain);
    if (cookieglob != null) {
      string[] cookies = cookieglob.split(";");
      for (string cookietuple : cookies) {
        string[] cookieparts = cookietuple.split("=");
        hashset<string> domainset = getdomainset(domain);
        for (string dm : domainset) {
          /* set an expire time so that this field will be removed after calling sync() */
          cookiemanager.setcookie(dm, cookieparts[0] + "=; expires=wed, 31 dec 2015 23:59:59 gmt");
        }
      }
      cookiemanager.sync();
    }
  }
 
  private static hashset<string> getdomainset(string domain) {
    hashset<string> domainset = new hashset<>();
    string host = uri.parse(domain).gethost();
 
    domainset.add(host);
    domainset.add("." + host);
    // exclude domain like "baidu.com"
    if (host.indexof(".") != host.lastindexof(".")) {
      domainset.add(host.substring(host.indexof('.')));
    }
 
    return domainset;
  }

以上这篇android实现清除单个域名的cookie就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网