Androidは、単一ドメイン名をクリアするクッキーを実現します。


今日PMは一つの需要を提供しました。ユーザーは現在のウェブページから退出する時、このウェブページのアクセスしたドメイン名に関するクッキーだけをクリアして、他のドメイン名のクッキーを保留します。
Cookie ManagerのAPIを調べたら、removeAll Cookieだけが、個別ドメイン名cookieのAPIをクリアしていませんでした。考えてみると、このような長年のブラウザを使っていますが、いつこの機能を見ましたか?
システムがインターフェースを提供していない以上、自分で何とかしてクリアするしかないです。
まず、Cookieの存在を明らかにしましょう。
で/data/data//ap_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,'.hm.baidu.com','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フィールドに含まれるすべての情報です。フェイスブックを例にとって、実際には、
Set-Cookie:m_ts=147810392datr=uxMaWFe 4 eAqp 6 W 2_dDu 2 Mp A 1fr=OEhMpmXi 6717 eJE 6 Y;path=/;domain=.facebook.com
これらの情報を削除しさえすれば、webviewは今度請求する時にはcookieが有効ではありません。最も直接的なアイデアは、Cookie Managerのset Cookie()メソッドを呼び出して、これらのフィールドをクリアしたり、期限切れにしたりすればいいじゃないですか?StockOverflowで調べてみましたが、似たような思想を討論するスレッドを見つけました。試してみましたが、やはりだめです。
リンク: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.comCookie Manager.get Cookie()で取得したパラメータは全く違います。この問題は一時間以上私を困らせました。パラメータがいくつかあることに気づきました。
2.Cookiesの表里に「.」で始まるドメイン名があります。例えば、表と裏の「.facebook.com」のように、いくつかのパラメータは完全なドメイン名で削除できません。たとえばhttp://www.facebook.comCookie Manager.set Cookie()を呼び出してフィールド情報をクリアしますと、テーブルの中に「www.facebook.com」という記録が追加されていますが、元の「.facebook.com」の記録はまだあります。フィールド情報はクリアされていません。
3.「.」で始まるドメイン名を使用して、「.facebook.com」のように、Cookie Manager.get Cookie()を呼び出した場合は、全パラメータリストが取得できません。
4.様々なサイトがCookiesの表に複数の記録を追加します。フェイスブックを例にとると、表には「wwww.facebook.com」、「.wwww.facebook.com」、「.facebook.com」の3種類の記録が保存される可能性があります。
最後に結論を言いましょう。何回かの紆余曲折を経て、ようやく使える方法を見つけました。5.1/6.0のプラットフォームを自分で測ってみます。実はとても簡単で粗暴で、上の第4条の言及したあのいくつかの記録をすべてかき集めて、むしろ間違って千を殺しても、ひとつを見逃しません。
コードを添付します。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を実現しました。小編集は皆さんに全部の内容を共有しました。皆様に参考にしてもらいたいです。