Cookie是啥
由于HTTP協(xié)議是無狀態(tài)的死讹,而服務器端的業(yè)務必須是要有狀態(tài)的站欺。Cookie誕生的最初目的是為了存儲web中的狀態(tài)信息作郭,以方便服務器端使用哨查。比如判斷用戶是否是第一次訪問網(wǎng)站逗抑。目前最新的規(guī)范是RFC 6265,它是一個由瀏覽器服務器共同協(xié)作實現(xiàn)的規(guī)范寒亥。
客戶端請求服務器之后,服務器通過Response的header攜帶Cookie,客戶端保存在本地,下次請求的時候,在客戶端request的header中攜帶這個Cookie
一個基本的Cookie結構如下
Set-Cookie: "name=value;domain=.domain.com;path=/;expires=Sat, 11 Jun 2016 11:29:42 GMT;HttpOnly;secure"
其中 name=value 是必選項邮府,其它都是可選項。Cookie的主要構成如下:
name: 一個唯一確定的cookie名稱溉奕。通常來講cookie的名稱是不區(qū)分大小寫的褂傀。
value:存儲在cookie中的字符串值。最好為cookie的name和value進行url編碼
domain:cookie對于哪個域是有效的加勤。所有向該域發(fā)送的請求中都會包含這個cookie信息仙辟。這個值可以包含子域(如:yq.aliyun.com)同波,也可以不包含它(如:.aliyun.com,則對于aliyun.com的所有子域都有效).
path: 表示這個cookie影響到的路徑叠国,瀏覽器跟會根據(jù)這項配置未檩,像指定域中匹配的路徑發(fā)送cookie。
expires:失效時間粟焊,表示cookie何時應該被刪除的時間戳(也就是冤狡,何時應該停止向服務器發(fā)送這個cookie)。如果不設置這個時間戳项棠,瀏覽器會在頁面關閉時即將刪除所有cookie悲雳;不過也可以自己設置刪除時間。這個值是GMT時間格式香追,如果客戶端和服務器端時間不一致合瓢,使用expires就會存在偏差。
max-age: 與expires作用相同透典,用來告訴瀏覽器此cookie多久過期(單位是秒)晴楔,而不是一個固定的時間點。正常情況下掷匠,max-age的優(yōu)先級高于expires滥崩。
HttpOnly: 告知瀏覽器不允許通過腳本document.cookie去更改這個值,同樣這個值在document.cookie中也不可見讹语。但在http請求張仍然會攜帶這個cookie钙皮。注意這個值雖然在腳本中不可獲取,但仍然在瀏覽器安裝目錄中以文件形式存在顽决。這項設置通常在服務器端設置短条。
secure: 安全標志,指定后才菠,只有在使用SSL鏈接時候才能發(fā)送到服務器茸时,如果是http鏈接則不會傳遞該信息。就算設置了secure 屬性也并不代表他人不能看到你機器本地保存的 cookie 信息赋访,所以不要把重要信息放cookie就對了服務器端設置
如何通過攔截http請求拿到cookie
okhttp3天然支持獲取cookie
只需要實現(xiàn)CookieJar
//攔截cookie
class LocalCookieJar implements CookieJar {
List<Cookie> cookies;
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
if (cookies != null)
return cookies;
return new ArrayList<Cookie>();
}
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
this.cookies = cookies;
//存儲當前cookie,用于webview中同步cookie
CookiesManager.getInstance().cookieMap.put(url,cookies)
}
}
并在okhttp的builder中添加cooloeJar
OkHttpClient mOkHttpClient = OkHttpUtils.newInstance().connectTimeout(45, TimeUnit.SECONDS)
.addInterceptor(new LogInterceptor())
.cookieJar(new LocalCookieJar(cookieHashMap))//添加cookie管理
.build();
在webview中同步cookie
以下代碼在我項目中親測有效,可能不同頁面針對cookie參數(shù)設置不同,請根據(jù)自身項目來傳所需要的cookie
webView.setWebViewClient(new CustomWebViewClient(mProgressWebView.getWebView()) {
/**
* 5.0以下
*/
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
synCookies(url);
return super.shouldInterceptRequest(view, url);//將加好cookie的url傳給父類繼續(xù)執(zhí)行
}
/**
*5.0以上
*/
@SuppressLint("NewApi")
@Override
public WebResourceResponse shouldInterceptRequest(WebView view , WebResourceRequest request) {
String url = request.getUrl().toString();
synCookies(url);
return super.shouldInterceptRequest(view, url);
}
});
public static void synCookies(String url){
if ( !TextUtils.isEmpty(url) )
if (!null!=cookies ) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
CookieSyncManager.createInstance( context);
}
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie( true );
cookieManager.removeSessionCookie();// 移除
cookieManager.removeAllCookie();
for (Cookie cookie : cookies) {
StringBuilder sbCookie = new StringBuilder();//創(chuàng)建一個拼接cookie的容器,
sbCookie.append(cookie.name()+"="+cookie.value());
sbCookie.append(";domain="+cookie.domain());
sbCookie.append(";path="+cookie.path());
String cookieValue = sbCookie.toString();
cookieManager.setCookie(url, cookieValue);//為url設置cookie
}
CookieSyncManager.getInstance().sync();//同步cookie
String newCookie = cookieManager.getCookie(url); //這里可以查看當前設置進去的cookie
}
}