Android实现清除单个域名的cookie
今天PM提了个需求:用户退出当前网页时,只清除该网页访问的域名相关的cookie,保留其他域名的cookie。
查了一下CookieManager的API,发现只有removeAllCookie(),没有清除单独域名cookie的API。。。想想也是,用了这么多年的浏览器,啥时候见过这功能?
既然系统没有提供接口,那就是只能自己想办法去清了。
首先要搞清楚Cookie存在哪里吧?
在/data/data/
sqlite>.tables cookiesmeta sqlite>.dumpcookies PRAGMAforeign_keys=OFF; BEGINTRANSACTION; CREATETABLEcookies(creation_utcINTEGERNOTNULLUNIQUEPRIMARYKEY,host_keyTEXTNOTNULL,nameTEXTNOTNULL,valueTEXTNOTNULL,pathTEXTNOTNULL,expires_utcINTEGERNOTNULL,secureINTEGERNOTNULL,httponlyINTEGERNOTNULL,last_access_utcINTEGERNOTNULL,has_expiresINTEGERNOTNULLDEFAULT1,persistentINTEGERNOTNULLDEFAULT1,priorityINTEGERNOTNULLDEFAULT1,encrypted_valueBLOBDEFAULT'',firstpartyonlyINTEGERNOTNULLDEFAULT0); INSERTINTO"cookies"VALUES(13122904895970126,'.hm.baidu.com','HMACCOUNT','1E0666871DC4BB45','/',13792186776970126,0,0,13122906283432123,1,1,1,X'',0); INSERTINTO"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); INSERTINTO"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); INSERTINTO"cookies"VALUES(13122905170227393,'.facebook.com','m_ts','1478103992','/',0,0,0,13122905170227393,0,0,1,X'',0); INSERTINTO"cookies"VALUES(13122905172258460,'.facebook.com','datr','uxMaWFe4eAqp6W2_dDu2MpA1','/',13185977172258460,0,1,13122905172258460,1,1,1,X'',0); INSERTINTO"cookies"VALUES(13122905172508865,'.facebook.com','fr','0EhMpmXi6717eJE6Y..BYGhO4.Dd.AAA.0.0.BYGhO7.AWUFjMmY','/',13130681172508865,0,1,13122905172508865,1,1,1,X'',0); CREATEINDEXdomainONcookies(host_key); CREATEINDEXis_transientONcookies(persistent)wherepersistent!=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上搜了一下,找到一个帖子讨论类似的思想,试了一下发现还是不行。。。
原文链接:http://stackoverflow.com/questions/2834180/how-to-remove-cookies-using-cookiemanager-for-a-specific-domain/11621738#11621738
下面说一说遇到的一堆坑吧:
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):
privatestaticvoiddeleteCookiesForDomain(Contextcontext,Stringdomain){ CookieManagercookieManager=CookieManager.getInstance(); if(cookieManager==null)return; /*http://code.google.com/p/android/issues/detail?id=19294*/ if(Build.VERSION.SDK_INT<11){ /*Trimleading'.'s*/ if(domain.startsWith("."))domain=domain.substring(1); } StringcookieGlob=cookieManager.getCookie(domain); if(cookieGlob!=null){ String[]cookies=cookieGlob.split(";"); for(StringcookieTuple:cookies){ String[]cookieParts=cookieTuple.split("="); HashSetdomainSet=getDomainSet(domain); for(Stringdm:domainSet){ /*Setanexpiretimesothatthisfieldwillberemovedaftercallingsync()*/ cookieManager.setCookie(dm,cookieParts[0]+"=;Expires=Wed,31Dec201523:59:59GMT"); } } cookieManager.sync(); } } privatestaticHashSet getDomainSet(Stringdomain){ HashSet domainSet=newHashSet<>(); Stringhost=Uri.parse(domain).getHost(); domainSet.add(host); domainSet.add("."+host); //excludedomainlike"baidu.com" if(host.indexOf(".")!=host.lastIndexOf(".")){ domainSet.add(host.substring(host.indexOf('.'))); } returndomainSet; }
以上这篇Android实现清除单个域名的cookie就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。