android WebView的cookie機(jī)制

將cookie同步到WebView(推薦)
參考:
文/CrazyCodeBoy(簡(jiǎn)書作者)
android WebView 和 HttpClient cookie同步

原理分析:

  • WebView是基于webkit內(nèi)核的UI控件,相當(dāng)于一個(gè)瀏覽器客戶端。它會(huì)在本地維護(hù)每次會(huì)話的cookie(保存在data/data/package_name/app_WebView/Cookies.db)。如圖:


    查看APP cookie

當(dāng)WebView加載URL的時(shí)候,WebView會(huì)從本地讀取該URL對(duì)應(yīng)的cookie,并攜帶該cookie與服務(wù)器進(jìn)行通信。WebView通過(guò)android.webkit.CookieManager類來(lái)維護(hù)cookie。CookieManager是WebView的cookie管理類。

  • CookieManager.setCookie()方法:
/** 
 * Sets a cookie for the given URL. Any existing cookie with the same host, 
 * path and name will be replaced with the new cookie. The cookie being set 
 * must not have expired and must not be a session cookie, otherwise it 
 * will be ignored. 
 * 
 * @param url the URL for which the cookie is set 
 * @param value the cookie as a string, using the format of the 'Set-Cookie' 
 *              HTTP response header 
 */  
public void setCookie(String url, String value) {  
    throw new MustOverrideException();  
}  

注:host、path和name相同的cookie 會(huì)被新的給替換掉,注意是host、path和name都相同的。
url參數(shù)是你要為哪個(gè)cookie設(shè)置,而value和服務(wù)器返回設(shè)置sookie的方法'Set-Cookie‘是一致的。
也就是一個(gè)url的多個(gè)cookie,要調(diào)用多次setCookie,而每一次調(diào)用value的值都類似于:

cookie + ";Max-Age=3600" + ";Domain=.163.com" + ";Path = /"  // 當(dāng)然還可以加上版本等信息  

一般寫法:

//value參數(shù)不要忘記加domain和path
cookieManager.setCookie(cookie.getDomain(), cookie.getName() + "=" + cookie.getValue() 
+ "; domain=" + cookie.getDomain() + "; path=" + cookie.getPath());

注意這里為什么第一個(gè)參數(shù)寫了個(gè)cookie.getDomain(),而不是像api里邊說(shuō)的url這涉及到了cookie的知識(shí),設(shè)置cookie時(shí),會(huì)先檢測(cè)cookie的Domain是否和url網(wǎng)址的域名一致,如果不一致設(shè)置cookie失敗。所以u(píng)rl在里邊起到作用,就是檢測(cè)Domain域名。

注意,只有cookie的domain和path與請(qǐng)求的URL匹配才會(huì)發(fā)送這個(gè)cookie,所以設(shè)置cookie的時(shí)候value參數(shù)不要忘記加domain和path,如上面代碼。

如何做:

下面我們就通過(guò)CookieManager將cookie同步到WebView中。之前同步cookie需要用到CookieSyncManager類,現(xiàn)在這個(gè)類已經(jīng)被deprecated。如今WebView已經(jīng)可以在需要的時(shí)候自動(dòng)同步cookie了,所以不再需要?jiǎng)?chuàng)建CookieSyncManager類的對(duì)象來(lái)進(jìn)行強(qiáng)制性的同步cookie了。現(xiàn)在只需要獲得 CookieManager的對(duì)象將cookie設(shè)置進(jìn)去就可以了。

  • 第一步:登錄時(shí)從服務(wù)器的返回頭中取出cookie**根據(jù)Http請(qǐng)求的客戶端不同,取cookie的方式也不同,我就不一一羅列了,需要的網(wǎng)友可以自行Google,以HttpURLcollection為例:
String cookieStr = conn.getHeaderField("Set-Cookie");
  • 第二步:將cookie同步到WebView中**
/**
 * 將cookie同步到WebView
 * @param url WebView要加載的url
 * @param cookie 要同步的cookie
 * @return true 同步cookie成功,false同步cookie失敗
 * @Author JPH
 */
public static boolean syncCookie(String url,String cookie) {
 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {   
      CookieSyncManager.createInstance(context);
 }  
  CookieManager cookieManager = CookieManager.getInstance();
    cookieManager.setCookie(url, cookie);//如果沒(méi)有特殊需求,這里只需要將session id以"key=value"形式作為cookie即可
    String newCookie = cookieManager.getCookie(url);
    return TextUtils.isEmpty(newCookie)?false:true;
}

如圖(url可以只到path即可):

同步cookie

如果設(shè)置成功,通過(guò)cookieManager.getCookie(url)
方法就可取得剛才設(shè)置的cookie,下面我們查看一下Cookie數(shù)據(jù)庫(kù)中發(fā)生的變化。如圖:


查看WebView cookie

提示:
同步cookie要在WebView加載url之前,否則WebView無(wú)法獲得相應(yīng)的cookie,也就無(wú)法通過(guò)驗(yàn)證。
每次登錄成功后都需要調(diào)用"syncCookie"方法將cookie同步到WebView中,同時(shí)也達(dá)到了更新WebView的cookie。如果登錄后沒(méi)有及時(shí)將cookie同步到WebView可能導(dǎo)致WebView拿的是舊的session id和服務(wù)器進(jìn)行通信。

優(yōu)點(diǎn):
方便,只需要在登陸后將cookie同步到WebView即可,省去了每次請(qǐng)求都需要設(shè)置一次的繁瑣。
兼容性好,因?yàn)槭窍到y(tǒng)原生支持的,所以兼容性自然比方式一要好,不存在cookie被攔截的問(wèn)題。

PS

Cookie相關(guān)的Http頭

有 兩個(gè)Http頭部和Cookie有關(guān):Set-Cookie和Cookie

  • Set-Cookie由服務(wù)器發(fā)送,它包含在響應(yīng)請(qǐng)求的頭部中。它用于在客戶端創(chuàng)建一個(gè)Cookie
  • Cookie頭由客戶端發(fā)送,包含在HTTP請(qǐng)求的頭部中。注意,只有cookie的domain和path與請(qǐng)求的URL匹配才會(huì)發(fā)送這個(gè)cookie。

Set-Cookie響應(yīng)頭的格式如下所示:

Set-Cookie: <name>=<value>[; <name>=<value>]...
   [; expires=<date>][; domain=<domain_name>]
   [; path=<some_path>][; secure][; httponly]

expires=<date>: 設(shè)置cookie的有效期,如果cookie超過(guò)date所表示的日期時(shí),cookie將失效。
如果沒(méi)有設(shè)置這個(gè)選項(xiàng),那么cookie將在瀏覽器關(guān)閉時(shí)失效。
secure : 表示cookie只能被發(fā)送到http服務(wù)器。
httponly : 表示cookie不能被客戶端腳本獲取到。

注:臨時(shí)cookie(沒(méi)有expires參數(shù)的cookie)不能帶有domain選項(xiàng)。
當(dāng)客戶端發(fā)送一個(gè)http請(qǐng)求時(shí),會(huì)將有效的cookie一起發(fā)送給服務(wù)器。
如果一個(gè)cookie的domain和path參數(shù)和URL匹配,那么這個(gè)cookie就是有效的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容