Cookie 是服务器发送到用户浏览器并保存在浏览器上的一块数据,它会在浏览器下一次发起请求时被携带并发送到服务器上。可通过Cookie保存浏览信息来获得更轻松的在线体验,比如保持登录状态、记住偏好设置,并提供本地的相关内容。
会话Cookie 与 持久Cookie
会话cookie不需要指定Expires和Max-Age,浏览器关闭之后它会被自动删除。
持久cookie指定了Expires或Max-Age,会被存储到磁盘上,不会因浏览器而失效。
第一方Cookie 与 第三方Cookie
每个Cookie都有与之关联的域,与页面域一样的就是第一方Cookie,不一样的就是第三方Cookie。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().setAcceptThirdPartyCookies(vWeb, true);
}
读取/写入/移除 Cookie
// 返回值使用"Cookie"请求头格式:"name=value; name2=value2; name3=value3"
CookieManager.getInstance().getCookie(url);
// 参数value使用"Set-Cookie"响应头格式,参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie
CookieManager.getInstance().setCookie(url, value);
CookieManager.getInstance().setCookie(url, cookieName + "=");
webkit cookie 工具类
// 移除指定url关联的所有cookie
public static void remove(String url) {
CookieManager cm = CookieManager.getInstance();
for (String cookie : cm.getCookie(url).split("; ")) {
cm.setCookie(url, cookie.split("=")[0] + "=");
}
flush();
}
// sessionOnly 为true表示移除所有会话cookie,否则移除所有cookie
public static void remove(boolean sessionOnly) {
CookieManager cm = CookieManager.getInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (sessionOnly) {
cm.removeSessionCookies(null);
} else {
cm.removeAllCookies(null);
}
} else {
if (sessionOnly) {
cm.removeSessionCookie();
} else {
cm.removeAllCookie();
}
}
flush();
}
// 写入磁盘
public static void flush() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().flush();
} else {
CookieSyncManager.getInstance().sync();
}
}
}
同步系统Cookie 与 Webkit Cookie
// 将系统级Cookie(比如`new URL(...).openConnection()`的Cookie) 同步到 WebView
public class WebkitCookieHandler extends CookieHandler {
private static final String TAG = WebkitCookieHandler.class.getSimpleName();
private CookieManager wcm;
public WebkitCookieHandler() {
this.wcm = CookieManager.getInstance();
}
@Override
public void put(URI uri, Map<String, List<String>> headers) throws IOException {
if ((uri == null) || (headers == null)) {
return;
}
String url = uri.toString();
for (String headerKey : headers.keySet()) {
if ((headerKey == null) || !(headerKey.equalsIgnoreCase("set-cookie2") || headerKey.equalsIgnoreCase("set-cookie"))) {
continue;
}
for (String headerValue : headers.get(headerKey)) {
Log.e(TAG, headerKey + ": " + headerValue);
this.wcm.setCookie(url, headerValue);
}
}
}
@Override
public Map<String, List<String>> get(URI uri, Map<String, List<String>> headers) throws IOException {
if ((uri == null) || (headers == null)) {
throw new IllegalArgumentException("Argument is null");
}
String url = uri.toString();
String cookie = this.wcm.getCookie(url);
Log.e(TAG, "cookie: " + cookie);
if (cookie != null) {
return Collections.singletonMap("Cookie", Arrays.asList(cookie));
} else {
return Collections.emptyMap();
}
}
}
缓存(Cache)
设置缓存模式
- WebSettings.LOAD_DEFAULT 根据cache-control决定是否从网络上取数据
- WebSettings.LOAD_CACHE_ELSE_NETWORK 无网,离线加载,优先加载缓存(即使已经过期)
- WebSettings.LOAD_NO_CACHE 仅从网络加载
- WebSettings.LOAD_CACHE_ONLY 仅从缓存加载
// 网络正常时根据cache-control决定是否从网络上取数据
if (isNetworkConnected(mActivity)) {
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
} else {
settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
清除缓存
// 传入true表示同时内存与磁盘,false表示仅清除内存
// 由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序
web.clearCache(true);
网友评论