在WebView訪問不同網(wǎng)址時,通常我們對具有相同域的Url有著種Cookie的需求刨肃,方便后續(xù)的客戶端與服務(wù)器的交互,省略用戶反復(fù)操作的過程箩帚。
為了達到這個目的真友,我們往往使用安卓提供的CookieManager類中的setCookie(String url, String value)方法來對url的Cookie進行設(shè)置。
首先看一下該方法的注釋:
/**
* 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
* will be ignored if it is expired.
*
* @param url the URL for which the cookie is to be set
* @param value the cookie as a string, using the format of the 'Set-Cookie'
* HTTP response header
*/
public abstract void setCookie(String url, String value);
該注釋說明了使用該方法時的兩點信息:
- 只有host紧帕,path和name相同的cookie才是相同的cookie马篮,才會在設(shè)置的時候覆蓋原有的cookie。否則經(jīng)測會并列存儲在cookie列表中豌习。
- 被設(shè)置的cookie如果已經(jīng)過期則可以忽略步责。
我們使用這兩個特點可以解決兩個問題:
- 什么情況下一個cookie才可以被使用在URL的訪問中
- 如何將特定的cookie在setCookie保存后并刪除
首先來解決第一個問題。
我們在WebView中使用Cookie時會偶爾失效鹅搪,這是為什么呢站绪?
我們要搞清楚,在Cookie中丽柿,host和path的意義是什么
domain(host)表示的是cookie所在的域恢准,默認為請求的地址,如網(wǎng)址為www.test.com/test/test.aspx甫题,那么domain默認為www.test.com馁筐。而跨域訪問,如域A為t1.test.com坠非,域B為t2.test.com敏沉,那么在域A生產(chǎn)一個令域A和域B都能訪問的cookie就要將該cookie的domain設(shè)置為.test.com;如果要在域A生產(chǎn)一個令域A不能訪問而域B能訪問的cookie就要將該cookie的domain設(shè)置為t2.test.com。
path表示cookie所在的目錄赦抖,asp.net默認為/舱卡,就是根目錄。在同一個服務(wù)器上有目錄如下:/test/,/test/cd/,/test/dd/队萤,現(xiàn)設(shè)一個cookie1的path為/test/轮锥,cookie2的path為/test/cd/,那么test下的所有頁面都可以訪問到cookie1要尔,而/test/和/test/dd/的子頁面不能訪問cookie2舍杜。這是因為cookie能讓其path路徑下的頁面訪問。
在這里引入我所遇見的問題赵辕,比如我想訪問一個URL:
String url = "www.baidu.com/test/app/";
已知用戶的session值既绩,所以我對該URL進行setCookie操作:
setCookie(url, "session=" + getSession());
這時存儲Cookie的數(shù)據(jù)表中的這一條Cookie存儲情況為
creation_utc | host_key | name | value | path | expires_utc | secure | httponly | last_access_utc | has_expires | persistent | priority | encrypted_value | firstpartyonly |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
13171714776494734 | www.baidu.com | session | 11111111 | /test/app | 0 | 0 | 0 | 13171714776494734 | 0 | 0 | 1 | (數(shù)據(jù)) | 0 |
我們可以看到,默認的host和path都是根據(jù)url進行判斷和存儲的还惠,這樣就會帶來一個問題饲握。如果我們想對相同host下的url都種上Cookie,那么這種path受限的Cookie是肯定不好使的蚕键,上面第二條也講過了救欧。
所以我們需要將Path設(shè)置為"path = /",這樣根目錄下的訪問就都可以使用這個Cookie了锣光,即修改上述設(shè)定Cookie的代碼為
setCookie(url, "session=" + getSession() + ";max-age=2534023007" + ";domain=" + host + ";path = /");
這里我們只關(guān)注最關(guān)鍵的path的設(shè)置就可以笆怠,接下來分析Cookie的過期機制。
第二個問題誊爹,Cookie的過期機制
首先我們在設(shè)置Cookie的時候蹬刷,可以設(shè)置Cookie的生效時間,字段名為expires或max-age频丘。前者為過期的時間點办成,后者為生效的持續(xù)時間,單位為秒搂漠。
在這里說幾個實驗結(jié)果:
如果將cookie的max-age設(shè)置為負數(shù)诈火,或者將expires字段設(shè)置為過期的時間點,數(shù)據(jù)庫更新后這條cookie將從數(shù)據(jù)庫中被刪除
如果將cookie的max-age和expires字段設(shè)置為正常的過期日期状答,則到期后在數(shù)據(jù)庫更新時會刪除該條數(shù)據(jù)
(筆者在這里嘗試了setCookie和getCookie兩種方法,都造成了數(shù)據(jù)庫的更新〉堆拢現(xiàn)在CookieManager已經(jīng)可以自動sync惊科,不需要強制sync)
所以如果我們想刪除數(shù)據(jù)庫中的某條Cookie,直接將它的時間設(shè)置為過期即可亮钦。
還需要注意一點
在更新Cookie時馆截,只有host,name(也就是key),path都相同時才會更新該條cookie蜡娶,否則只會在數(shù)據(jù)庫中增加新的條目混卵。