sessionStorage、localStorage、cookie
文章目錄
- 1. cookie
- 2. Storage
1. cookie
document.cookie
1.1. 會話期Cookie
會話期Cookie是最簡單的Cookie:瀏覽器關閉之後它會被自動刪除,也就是說它僅在會話期內有效。會話期Cookie不需要指定過期時間(Expires)或者有效期(Max-Age)。需要注意的是,有些瀏覽器提供了會話恢復功能,這種情況下即使關閉了瀏覽器,會話期Cookie也會被保留下來,就好像瀏覽器從來沒有關閉一樣。
1.2. 永續性Cookie
和關閉瀏覽器便失效的會話期Cookie不同,永續性Cookie可以指定一個特定的過期時間(Expires)或有效期(Max-Age)
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
提示:當Cookie的過期時間被設定時,設定的日期和時間只與客戶端相關,而不是服務端。
1.3. 寫cookie
document.cookie='key=value'
使用document.cookie=
,新增或者更新當前cookie,並不是將原來的所有cookie都替換了。
如果沒有設定expires
或者max-age
,那麼這個cookie就是會話級cookie(標籤或者瀏覽器關閉時,會被清除.但這並非一定的).否則,就是持久cookie
設定cookie的其它屬性:
document.cookie='key=value;expires='+(new Date()).toUTCString()+";path=/;domain=test.com;secure;httponly;"
1.3.1. expires
指定到期時間.UTC時間字串,如果設定為當前時間,cookie被刪除
1.3.2. max-age
指定有效期,單位秒.這是一個用來替代expires
的屬性.因此作用和expires
相同.
1.3.3. path
Path標識指定了主機下的哪些路徑可以接受Cookie(該URL路徑必須存在於請求URL中)。以字元 %x2F ("/") 作為路徑分隔符,子路徑也會被匹配。
例如,設定 Path=/docs,則以下地址都會匹配:
/docs
/docs/Web/
/docs/Web/HTTP
但是,設定path並不能有效的阻止cookie被竊取.一種方法是在當前頁面嵌入iframe,然後將iframe指向cookie要求的路徑,這樣就可以實現跨路徑獲取cookie了
1.3.4. domain
Domain 標識指定了哪些主機可以接受Cookie。如果不指定,預設為當前文件的主機(不包含子域名)。如果指定了Domain,則一般包含子域名。
例如,如果設定 Domain=mozilla.org,則Cookie也包含在子域名中(如developer.mozilla.org)。
1.3.5. secure
標記為secure的cookie,只能用於https.使用時,只用寫上secure
即可,無需設定值;需要取消時,可重新設定cookie,後邊不帶secure也就是了.
1.3.6. httponly
不允許javascript獲取,只用於http傳輸.和secure一樣,只需要寫上httponly
標記一下即可.
1.4. 獲取cookie
var allCookie = document.cookie;
獲取到的allCookie
是一個key=value
並以分號隔開的字串.沒有expires
/path
/domain
/max-age
等說明欄位
1.5. 刪除cookie
//刪除cookie有兩種方法
//1. 設定expires為當前時間
document.cookie='key=value;expires='+(new Date()).toUTCString()
//2. 設定max-age為0
document.cookie='key=value;max-age=0'
1.6. MDN操作cookie的示例
/*\
|*|
|*| :: cookies.js ::
|*|
|*| A complete cookies reader/writer framework with full unicode support.
|*|
|*| Revision #3 - July 13th, 2017
|*|
|*| https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
|*| https://developer.mozilla.org/User:fusionchess
|*| https://github.com/madmurphy/cookies.js
|*|
|*| This framework is released under the GNU Public License, version 3 or later.
|*| http://www.gnu.org/licenses/gpl-3.0-standalone.html
|*|
|*| Syntaxes:
|*|
|*| * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
|*| * docCookies.getItem(name)
|*| * docCookies.removeItem(name[, path[, domain]])
|*| * docCookies.hasItem(name)
|*| * docCookies.keys()
|*|
\*/
var docCookies = {
getItem: function (sKey) {
if (!sKey) { return null; }
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
},
setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
var sExpires = "";
if (vEnd) {
switch (vEnd.constructor) {
case Number:
sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
/*
Note: Despite officially defined in RFC 6265, the use of `max-age` is not compatible with any
version of Internet Explorer, Edge and some mobile browsers. Therefore passing a number to
the end parameter might not work as expected. A possible solution might be to convert the the
relative time to an absolute time. For instance, replacing the previous line with:
*/
/*
sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; expires=" + (new Date(vEnd * 1e3 + Date.now())).toUTCString();
*/
break;
case String:
sExpires = "; expires=" + vEnd;
break;
case Date:
sExpires = "; expires=" + vEnd.toUTCString();
break;
}
}
document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
return true;
},
removeItem: function (sKey, sPath, sDomain) {
if (!this.hasItem(sKey)) { return false; }
document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
return true;
},
hasItem: function (sKey) {
if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
},
keys: function () {
var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
return aKeys;
}
};
2. Storage
作為 Web Storage API 的介面,Storage 提供了訪問特定域名下的會話儲存(session storage)或本地儲存(local storage)的功能,例如,可以新增、修改或刪除儲存的資料項。
如果你想要操作一個域名的會話儲存(session storage),可以使用 Window.sessionStorage;如果想要操作一個域名的本地儲存(local storage),可以使用 Window.localStorage。
sessionStorage instanceof Storage
//true
localStorage instanceof Storage
//true
因為sessionStorage
和localStorage
都實現了Storage
介面,因此它們都具備Storage
的屬性和方法
屬性:Storage.length
只讀
返回一個整數,表示儲存在 Storage
物件中的資料項數量。
方法:
Storage.key()
:該方法接受一個數值 n 作為引數,並返回儲存中的第 n 個鍵名。
Storage.getItem()
:該方法接受一個鍵名作為引數,返回鍵名對應的值。
Storage.setItem()
:該方法接受一個鍵名和值作為引數,將會把鍵值對新增到儲存中,如果鍵名存在,則更新其對應的值。
Storage.removeItem()
:該方法接受一個鍵名作為引數,並把該鍵名從儲存中刪除。
Storage.clear()
:呼叫該方法會清空儲存中的所有鍵名。
2.1. sessionStorage
sessionStorage 屬性允許你訪問一個 session Storage 物件。它與 localStorage 相似,不同之處在於 localStorage 裡面儲存的資料沒有過期時間設定,而儲存在 sessionStorage 裡面的資料在頁面會話結束時會被清除。頁面會話在瀏覽器開啟期間一直保持,並且重新載入或恢復頁面仍會保持原來的頁面會話。在新標籤或視窗開啟一個頁面時會在頂級瀏覽上下文中初始化一個新的會話,這點和 session cookies 的執行方式不同。
應該注意的是,無論是 localStorage 還是 sessionStorage 中儲存的資料都僅限於該頁面的協議。
2.2. localStorage
只讀的localStorage 允許你訪問一個Document 的遠端(origin)物件 Storage;資料儲存為跨瀏覽器會話。 localStorage 類似於sessionStorage。區別在於,資料儲存在 localStorage 是無期限的,而當頁面會話結束——也就是說當頁面被關閉時,資料儲存在sessionStorage 會被清除 。
應注意無論資料儲存在 localStorage 還是 sessionStorage ,它們都特定於頁面的協議。