我想要移除一个域名下的所有cookies,有没有方法可以做到这一点?
我所知道的唯一方法是使用removeAllCookies。
谢谢。
我想要移除一个域名下的所有cookies,有没有方法可以做到这一点?
我所知道的唯一方法是使用removeAllCookies。
谢谢。
setCookie()
来清除一个网站的cookie。如下所示,
为给定的URL设置一个cookie。任何具有相同主机、路径和名称的现有cookie都将被新cookie替换。如果cookie已过期,则设置的cookie将被忽略。
所以,解决方案是,如this答案中所述,我们需要手动清理每个主机键的每个cookie。例如:- facebookandroid.webkit.CookieManager.getInstance().setCookie(".facebook.com", "locale=;Max-Age=0");
android.webkit.CookieManager.getInstance().setCookie(".facebook.com", "datr=;Max-Age=0");
android.webkit.CookieManager.getInstance().setCookie(".facebook.com", "s=;Max-Age=0");
android.webkit.CookieManager.getInstance().setCookie(".facebook.com", "csm=;Max-Age=0");
android.webkit.CookieManager.getInstance().setCookie(".facebook.com", "fr=;Max-Age=0");
android.webkit.CookieManager.getInstance().setCookie(".facebook.com", "lu=;Max-Age=0");
android.webkit.CookieManager.getInstance().setCookie(".facebook.com", "c_user=;Max-Age=0");
android.webkit.CookieManager.getInstance().setCookie(".facebook.com", "xs=;Max-Age=0");
Max-Age=0
来真正删除cookie,否则你只是清除了它的值。 - undefinedCookieManager
类。虽然有一个清除cookie的方法removeAllCookie()
,但该方法在API级别21中已被弃用,因此您可以使用removeAllCookeis(callback)
方法。如果您不需要知道操作何时完成或是否删除了任何cookie,则可以将null
作为回调传递,并且在这种情况下,从没有Looper的线程调用该方法是安全的。CookieManager.getInstance().removeAllCookies(null);
CookieManager.getInstance().flush();
CookieSyncManager cookieSyncMngr=CookieSyncManager.createInstance(context);
cookieSyncMngr.startSync();
CookieManager cookieManager=CookieManager.getInstance();
cookieManager.removeAllCookie();
cookieManager.removeSessionCookie();
cookieSyncMngr.stopSync();
cookieSyncMngr.sync();
Let'sRefactor
和AnT
的答案对我找到最终解决方案很有帮助。因此,基本上我们需要逐个清理每个cookie。但对我而言,仅设置"value="
或"value=; Domain=my.domain.com"
并不起作用。我想这是页面的问题,我对该页面没有控制权(它在读取cookies时打印崩溃堆栈)。因此,对我来说,最终解决方案是删除cookies,而不是清空它们。当然,我们没有任何API来删除特定的cookie,但我们可以使用'Set-Cookie'
HTTP响应头格式的Max-Age参数。我的最终代码如下(Kotlin,在生产代码中我当然会将字符串放入常量中 ;)):
val domain = myPageUri.host
CookieManager.getInstance().apply {
getCookie(domain)
.split("; ")
.filter { it.isNotNullOrBlank() }
.forEach {
val newCookieValue = it.substringBefore("=") + "=; Max-Age=-1"
setCookie(domain, newCookieValue)
}
}
substringBefore(character: String)
是我们在 String
上的扩展函数,它返回从开头到第一次出现 character
的子字符串。
; Path=<path>
值,否则它不起作用,而这是您无法使用 CookieManager
获得的。您可以使用 WebViewClient
拦截请求,但在我的情况下这没有意义,所以我可能会删除所有可能路径的 cookie:url.toHttpUrl().encodedPathSegments.scan("/") { prefix, segment -> "$prefix$segment/" }
- arekolekvalue - String:cookie字符串,使用“Set-Cookie”HTTP响应头格式
我编写了以下代码来从任何特定域中删除cookie:
public static void deleteCookies(String url) {
CookieManager cookieManager = CookieManager.getInstance();
try {
String domainName = Utils.getDomainName(url);
String cookiesString = cookieManager.getCookie(url);
String[] cookies = cookiesString.split("; ");
for (String cookie : cookies) {
if (Strings.isNullOrEmpty(cookie))
continue;
int equalCharIndex = cookie.indexOf('=');
if (equalCharIndex == -1)
continue;
String cookieString = cookie.substring(0, equalCharIndex) + '='
+ "; Domain=" + domainName;
cookieManager.setCookie(url, cookieString);
}
} catch (URISyntaxException e) {
Log.e("TAG", "Message", e);
}
}
public static String getDomainName(@NotNull String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost();
domain = domain.startsWith("www.") ? domain.substring(4) : domain;
try {
//Try to get the domain without subdomain. Ex: mobile.twitter.com would returns twitter.com
//Note: InternetDomainName is from Guava library
return InternetDomainName.from(domain).topPrivateDomain().toString();
} catch (IllegalStateException e) {
Log.e("getDomainName()", "Illegal url");
}
return domain;
}
其他答案对我没有用,因为它们没有为 cookie 设置正确的路径。
对我有效的方法似乎是:
import android.webkit.CookieManager
import okhttp3.HttpUrl.Companion.toHttpUrl
fun CookieManager.removeCookies(url: String) {
val cookies = getCookie(url) ?: return
// Android SDK will not tell us what path was used to set the cookie, so we remove the cookie for all possible paths
val paths = url.toHttpUrl().encodedPathSegments.scan("/") { prefix, segment -> "$prefix$segment/" }
val keys = cookies.split(";")
.map { it.substringBefore("=", missingDelimiterValue = "").trim() }
.filter { it.isNotEmpty() }
.distinct()
keys.forEach { key ->
paths.forEach {
// Max-Age effectively removes the cookie
setCookie(url, "$key=; Path=$it; Max-Age=-1")
}
}
}