摘要:正文開始三種本地存儲方式前言網(wǎng)絡(luò)早期最大的問題之一是如何管理狀態(tài)。這個特點很重要,因為這關(guān)系到什么樣的數(shù)據(jù)適合存儲在中。特點生命周期持久化的本地存儲,除非主動刪除數(shù)據(jù),否則數(shù)據(jù)是永遠(yuǎn)不會過期的。
最近一直在搞基礎(chǔ)的東西,弄了一個持續(xù)更新的github筆記,可以去看看,誠意之作(本來就是寫給自己看的……)鏈接地址:Front-End-Basics
此篇文章的地址:三種本地存儲方式
基礎(chǔ)筆記的github地址:https://github.com/qiqihaobenben/Front-End-Basics ,可以watch,也可以star。
發(fā)完之后,就有同學(xué)表示,你這也不全呀,還有評論說:吹牛不交稅……,應(yīng)該是被人舉報了,現(xiàn)在看不到那條評論了,但是我郵箱里面有哦……本人水平有限只用過那三種,不過人家說的也是事實,我就有兩個想法,第一是把標(biāo)題改為“不太全的前端本地存儲講解”,第二種是把那不全的盡力補(bǔ)一下,嗯,做對的事情,我選擇了第二種,補(bǔ)充的東西在最后。正文開始…… 三種本地存儲方式 cookie 前言
網(wǎng)絡(luò)早期最大的問題之一是如何管理狀態(tài)。簡而言之,服務(wù)器無法知道兩個請求是否來自同一個瀏覽器。當(dāng)時最簡單的方法是在請求時,在頁面中插入一些參數(shù),并在下一個請求中傳回參數(shù)。這需要使用包含參數(shù)的隱藏的表單,或者作為URL參數(shù)的一部分傳遞。這兩個解決方案都手動操作,容易出錯。cookie出現(xiàn)來解決這個問題。
作用cookie是純文本,沒有可執(zhí)行代碼。存儲數(shù)據(jù),當(dāng)用戶訪問了某個網(wǎng)站(網(wǎng)頁)的時候,我們就可以通過cookie來向訪問者電腦上存儲數(shù)據(jù),或者某些網(wǎng)站為了辨別用戶身份、進(jìn)行session跟蹤而儲存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)
如何工作當(dāng)網(wǎng)頁要發(fā)http請求時,瀏覽器會先檢查是否有相應(yīng)的cookie,有則自動添加在request header中的cookie字段中。這些是瀏覽器自動幫我們做的,而且每一次http請求瀏覽器都會自動幫我們做。這個特點很重要,因為這關(guān)系到“什么樣的數(shù)據(jù)適合存儲在cookie中”。
存儲在cookie中的數(shù)據(jù),每次都會被瀏覽器自動放在http請求中,如果這些數(shù)據(jù)并不是每個請求都需要發(fā)給服務(wù)端的數(shù)據(jù),瀏覽器這設(shè)置自動處理無疑增加了網(wǎng)絡(luò)開銷;但如果這些數(shù)據(jù)是每個請求都需要發(fā)給服務(wù)端的數(shù)據(jù)(比如身份認(rèn)證信息),瀏覽器這設(shè)置自動處理就大大免去了重復(fù)添加操作。所以對于那種設(shè)置“每次請求都要攜帶的信息(最典型的就是身份認(rèn)證信息)”就特別適合放在cookie中,其他類型的數(shù)據(jù)就不適合了。
特征不同的瀏覽器存放的cookie位置不一樣,也是不能通用的。
cookie的存儲是以域名形式進(jìn)行區(qū)分的,不同的域下存儲的cookie是獨立的。
我們可以設(shè)置cookie生效的域(當(dāng)前設(shè)置cookie所在域的子域),也就是說,我們能夠操作的cookie是當(dāng)前域以及當(dāng)前域下的所有子域
一個域名下存放的cookie的個數(shù)是有限制的,不同的瀏覽器存放的個數(shù)不一樣,一般為20個。
每個cookie存放的內(nèi)容大小也是有限制的,不同的瀏覽器存放大小不一樣,一般為4KB。
cookie也可以設(shè)置過期的時間,默認(rèn)是會話結(jié)束的時候,當(dāng)時間到期自動銷毀
cookie值既可以設(shè)置,也可以讀取。 設(shè)置客戶端設(shè)置
document.cookie = "名字=值"; document.cookie = "username=cfangxu;domain=baike.baidu.com" 并且設(shè)置了生效域
注意: 客戶端可以設(shè)置cookie 的下列選項:expires、domain、path、secure(有條件:只有在https協(xié)議的網(wǎng)頁中,客戶端設(shè)置secure類型的 cookie 才能成功),但無法設(shè)置HttpOnly選項。
服務(wù)器端設(shè)置
不管你是請求一個資源文件(如 html/js/css/圖片),還是發(fā)送一個ajax請求,服務(wù)端都會返回response。而response header中有一項叫set-cookie,是服務(wù)端專門用來設(shè)置cookie的。
Set-Cookie 消息頭是一個字符串,其格式如下(中括號中的部分是可選的): Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
注意: 一個set-Cookie字段只能設(shè)置一個cookie,當(dāng)你要想設(shè)置多個 cookie,需要添加同樣多的set-Cookie字段。
服務(wù)端可以設(shè)置cookie 的所有選項:expires、domain、path、secure、HttpOnly
通過 Set-Cookie 指定的這些可選項只會在瀏覽器端使用,而不會被發(fā)送至服務(wù)器端。
我們通過document.cookie來獲取當(dāng)前網(wǎng)站下的cookie的時候,得到的字符串形式的值,它包含了當(dāng)前網(wǎng)站下所有的cookie(為避免跨域腳本(xss)攻擊,這個方法只能獲取非 HttpOnly 類型的cookie)。它會把所有的cookie通過一個分號+空格的形式串聯(lián)起來,例如username=chenfangxu; job=coding
修改 cookie要想修改一個cookie,只需要重新賦值就行,舊的值會被新的值覆蓋。但要注意一點,在設(shè)置新cookie時,path/domain這幾個選項一定要舊cookie 保持一樣。否則不會修改舊值,而是添加了一個新的 cookie。
刪除把要刪除的cookie的過期時間設(shè)置成已過去的時間,path/domain/這幾個選項一定要舊cookie 保持一樣。
注意如果只設(shè)置一個值,那么算cookie中的value; 設(shè)置的兩個cookie,key值如果設(shè)置的相同,下面的也會把上面的覆蓋。
cookie的屬性(可選項) 過期時間如果我們想長時間存放一個cookie。需要在設(shè)置這個cookie的時候同時給他設(shè)置一個過期的時間。如果不設(shè)置,cookie默認(rèn)是臨時存儲的,當(dāng)瀏覽器關(guān)閉進(jìn)程的時候自動銷毀
注意:document.cookie = "名稱=值;expires=" + GMT(格林威治時間)格式的日期型字符串;
一般設(shè)置天數(shù):new Date().setDate( oDate.getDate() + 5 ); 比當(dāng)前時間多5天
一個設(shè)置cookie時效性的例子
function setCookie(c_name, value, expiredays){ var exdate=new Date(); exdate.setDate(exdate.getDate() + expiredays); document.cookie=c_name+ "=" + escape(value) + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString()) } 使用方法:setCookie("username","cfangxu",30)
expires 是 http/1.0協(xié)議中的選項,在新的http/1.1協(xié)議中expires已經(jīng)由 max-age 選項代替,兩者的作用都是限制cookie 的有效時間。expires的值是一個時間點(cookie失效時刻= expires),而max-age 的值是一個以秒為單位時間段(cookie失效時刻= 創(chuàng)建時刻+ max-age)。cookie的域概念(domain選項)
另外,max-age 的默認(rèn)值是 -1(即有效期為 session );max-age有三種可能值:負(fù)數(shù)、0、正數(shù)。
負(fù)數(shù):有效期session;
0:刪除cookie;
正數(shù):有效期為創(chuàng)建時刻+ max-age
domain指定了 cookie 將要被發(fā)送至哪個或哪些域中。默認(rèn)情況下,domain 會被設(shè)置為創(chuàng)建該 cookie 的頁面所在的域名,所以當(dāng)給相同域名發(fā)送請求時該 cookie 會被發(fā)送至服務(wù)器。
瀏覽器會把 domain 的值與請求的域名做一個尾部比較(即從字符串的尾部開始比較),并將匹配的 cookie 發(fā)送至服務(wù)器。
客戶端設(shè)置document.cookie = "username=cfangxu;path=/;domain=qq.com"
如上:“www.qq.com" 與 "sports.qq.com" 公用一個關(guān)聯(lián)的域名"qq.com",我們?nèi)绻胱?"sports.qq.com" 下的cookie被 "www.qq.com" 訪問,我們就需要用到 cookie 的domain屬性,并且需要把path屬性設(shè)置為 "/"。
Set-Cookie: username=cfangxu;path=/;domain=qq.com
注:一定的是同域之間的訪問,不能把domain的值設(shè)置成非主域的域名。
cookie 一般都是由于用戶訪問頁面而被創(chuàng)建的,可是并不是只有在創(chuàng)建 cookie 的頁面才可以訪問這個 cookie。
因為安全方面的考慮,默認(rèn)情況下,只有與創(chuàng)建 cookie 的頁面在同一個目錄或子目錄下的網(wǎng)頁才可以訪問。
即path屬性可以為服務(wù)器特定文檔指定cookie,這個屬性設(shè)置的url且?guī)в羞@個前綴的url路徑都是有效的。
?最常用的例子就是讓 cookie 在根目錄下,這樣不管是哪個子頁面創(chuàng)建的 cookie,所有的頁面都可以訪問到了。
document.cookie = "username=cfangxu; path=/"
服務(wù)端設(shè)置Set-Cookie:name=cfangxu; path=/blog
如上設(shè)置:path 選項值會與 /blog,/blogrool 等等相匹配;任何以 /blog 開頭的選項都是合法的。需要注意的是,只有在 domain 選項核實完畢之后才會對 path 屬性進(jìn)行比較。path 屬性的默認(rèn)值是發(fā)送 Set-Cookie 消息頭所對應(yīng)的 URL 中的 path 部分。
domain和path總結(jié):domain是域名,path是路徑,兩者加起來就構(gòu)成了 URL,domain和path一起來限制 cookie 能被哪些 URL 訪問。
所以domain和path2個選項共同決定了cookie何時被瀏覽器自動添加到請求頭部中發(fā)送出去。如果沒有設(shè)置這兩個選項,則會使用默認(rèn)值。domain的默認(rèn)值為設(shè)置該cookie的網(wǎng)頁所在的域名,path默認(rèn)值為設(shè)置該cookie的網(wǎng)頁所在的目錄。
通常 cookie 信息都是使用HTTP連接傳遞數(shù)據(jù),這種傳遞方式很容易被查看,所以 cookie 存儲的信息容易被竊取。假如 cookie 中所傳遞的內(nèi)容比較重要,那么就要求使用加密的數(shù)據(jù)傳輸。
secure選項用來設(shè)置cookie只在確保安全的請求中才會發(fā)送。當(dāng)請求是HTTPS或者其他安全協(xié)議時,包含 secure 選項的 cookie 才能被發(fā)送至服務(wù)器。
document.cookie = "username=cfangxu; secure"
把cookie設(shè)置為secure,只保證 cookie 與服務(wù)器之間的數(shù)據(jù)傳輸過程加密,而保存在本地的 cookie文件并不加密。就算設(shè)置了secure 屬性也并不代表他人不能看到你機(jī)器本地保存的 cookie 信息。機(jī)密且敏感的信息絕不應(yīng)該在 cookie 中存儲或傳輸,因為 cookie 的整個機(jī)制原本都是不安全的
注意:如果想在客戶端即網(wǎng)頁中通過 js 去設(shè)置secure類型的 cookie,必須保證網(wǎng)頁是https協(xié)議的。在http協(xié)議的網(wǎng)頁中是無法設(shè)置secure類型cookie的。
httpOnly這個選項用來設(shè)置cookie是否能通過 js 去訪問。默認(rèn)情況下,cookie不會帶httpOnly選項(即為空),所以默認(rèn)情況下,客戶端是可以通過js代碼去訪問(包括讀取、修改、刪除等)這個cookie的。當(dāng)cookie帶httpOnly選項時,客戶端則無法通過js代碼去訪問(包括讀取、修改、刪除等)這個cookie。
在客戶端是不能通過js代碼去設(shè)置一個httpOnly類型的cookie的,這種類型的cookie只能通過服務(wù)端來設(shè)置。
cookie的編碼cookie其實是個字符串,但這個字符串中等號、分號、空格被當(dāng)做了特殊符號。所以當(dāng)cookie的 key 和 value 中含有這3個特殊字符時,需要對其進(jìn)行額外編碼,一般會用escape進(jìn)行編碼,讀取時用unescape進(jìn)行解碼;當(dāng)然也可以用encodeURIComponent/decodeURIComponent或者encodeURI/decodeURI,查看關(guān)于編碼的介紹
第三方cookie通常cookie的域和瀏覽器地址的域匹配,這被稱為第一方cookie。那么第三方cookie就是cookie的域和地址欄中的域不匹配,這種cookie通常被用在第三方廣告網(wǎng)站。為了跟蹤用戶的瀏覽記錄,并且根據(jù)收集的用戶的瀏覽習(xí)慣,給用戶推送相關(guān)的廣告。
關(guān)于第三方cookie和cookie的安全問題可以查看https://mp.weixin.qq.com/s/oOGIuJCplPVW3BuIx9tNQg
cookie推薦資源
聊一聊 cookie
HTTP cookies 詳解
localStorage(本地存儲)HTML5新方法,不過IE8及以上瀏覽器都兼容。
特點生命周期:持久化的本地存儲,除非主動刪除數(shù)據(jù),否則數(shù)據(jù)是永遠(yuǎn)不會過期的。
存儲的信息在同一域中是共享的。
當(dāng)本頁操作(新增、修改、刪除)了localStorage的時候,本頁面不會觸發(fā)storage事件,但是別的頁面會觸發(fā)storage事件。
大小:據(jù)說是5M(跟瀏覽器廠商有關(guān)系)
在非IE下的瀏覽中可以本地打開。IE瀏覽器要在服務(wù)器中打開。
localStorage本質(zhì)上是對字符串的讀取,如果存儲內(nèi)容多的話會消耗內(nèi)存空間,會導(dǎo)致頁面變卡
localStorage受同源策略的限制
設(shè)置localStorage.setItem("username","cfangxu");
獲取localStorage.getItem("username")
也可以獲取鍵名
localStorage.key(0) #獲取第一個鍵名
localStorage.removeItem("username")
也可以一次性清除所有存儲
localStorage.clear()
當(dāng)storage發(fā)生改變的時候觸發(fā)。
注意: 當(dāng)前頁面對storage的操作會觸發(fā)其他頁面的storage事件
事件的回調(diào)函數(shù)中有一個參數(shù)event,是一個StorageEvent對象,提供了一些實用的屬性,如下表:
Property | Type | Description |
---|---|---|
key | String | The named key that was added, removed, or moddified |
oldValue | Any | The previous value(now overwritten), or null if a new item was added |
newValue | Any | The new value, or null if an item was added |
url/uri | String | The page that called the method that triggered this change |
其實跟localStorage差不多,也是本地存儲,會話本地存儲
特點:用于本地存儲一個會話(session)中的數(shù)據(jù),這些數(shù)據(jù)只有在同一個會話中的頁面才能訪問并且當(dāng)會話結(jié)束后數(shù)據(jù)也隨之銷毀。因此sessionStorage不是一種持久化的本地存儲,僅僅是會話級別的存儲。也就是說只要這個瀏覽器窗口沒有關(guān)閉,即使刷新頁面或進(jìn)入同源另一頁面,數(shù)據(jù)仍然存在。關(guān)閉窗口后,sessionStorage即被銷毀,或者在新窗口打開同源的另一個頁面,sessionStorage也是沒有的。
cookie、localStorage、sessionStorage區(qū)別相同:在本地(瀏覽器端)存儲數(shù)據(jù)
不同:
localStorage、sessionStorage
localStorage只要在相同的協(xié)議、相同的主機(jī)名、相同的端口下,就能讀取/修改到同一份localStorage數(shù)據(jù)。
sessionStorage比localStorage更嚴(yán)苛一點,除了協(xié)議、主機(jī)名、端口外,還要求在同一窗口(也就是瀏覽器的標(biāo)簽頁)下。
localStorage是永久存儲,除非手動刪除。
sessionStorage當(dāng)會話結(jié)束(當(dāng)前頁面關(guān)閉的時候,自動銷毀)
cookie的數(shù)據(jù)會在每一次發(fā)送http請求的時候,同時發(fā)送給服務(wù)器而localStorage、sessionStorage不會。
先說個會被取代的,為什么會被取代,主要有以下幾個原因:
W3C舍棄 Web SQL database草案,而且是在2010年年底,規(guī)范不支持了,瀏覽器廠商已經(jīng)支持的就支持了,沒有支持的也不打算支持了,比如IE和Firefox。
為什么要舍棄?因為 Web SQL database 本質(zhì)上是一個關(guān)系型數(shù)據(jù)庫,后端可能熟悉,但是前端就有很多不熟悉了,雖然SQL的簡單操作不難,但是也得需要學(xué)習(xí)。
SQL熟悉后,真實操作中還得把你要存儲的東西,比如對象,轉(zhuǎn)成SQL語句,也挺麻煩的。
indexedDB來自MDN的解釋: indexedDB 是一種低級API,用于客戶端存儲大量結(jié)構(gòu)化數(shù)據(jù)(包括, 文件/ blobs)。該API使用索引來實現(xiàn)對該數(shù)據(jù)的高性能搜索。雖然 Web Storage 對于存儲較少量的數(shù)據(jù)很有用,但對于存儲更大量的結(jié)構(gòu)化數(shù)據(jù)來說,這種方法不太有用。IndexedDB提供了一個解決方案。
所以,IndexedDB API是強(qiáng)大的,但對于簡單的情況可能看起來太復(fù)雜了,所以要看你的業(yè)務(wù)場景來選擇到底是用還是不用。
indexedDB 是一個基于JavaScript的面向?qū)ο蟮臄?shù)據(jù)庫。 IndexedDB允許你存儲和檢索用鍵索引的對象;
IndexedDB 鼓勵使用的基本模式如下所示:
打開數(shù)據(jù)庫并且開始一個事務(wù)。
創(chuàng)建一個 object store。
構(gòu)建一個請求來執(zhí)行一些數(shù)據(jù)庫操作,像增加或提取數(shù)據(jù)等。
通過監(jiān)聽正確類型的 DOM 事件以等待操作完成。
在操作結(jié)果上進(jìn)行一些操作(可以在 request 對象中找到)
1、首先打開indexedDB數(shù)據(jù)庫語法:
window.indexedDB.open(dbName, version)
var db; // 打開數(shù)據(jù)庫,open還有第二個參數(shù)版本號 var request = window.indexedDB.open("myTestDatabase"); // 數(shù)據(jù)庫打開成功后 request.onsuccess = function (event) { // 存儲數(shù)據(jù)結(jié)果,后面所有的數(shù)據(jù)庫操作都離不開它。 db = request.result; } request.onerror = function (event) { alert("Why didn"t you allow my web app to use IndexedDB?!"); } // 數(shù)據(jù)庫首次創(chuàng)建版本,或者window.indexedDB.open傳遞的新版本(版本數(shù)值要比現(xiàn)在的高) request.onupgradeneeded = function (event) { }
onupgradeneeded事件: 更新數(shù)據(jù)庫的 schema,也就是創(chuàng)建或者刪除對象存儲空間,這個事件將會作為一個允許你處理對象存儲空間的 versionchange 事務(wù)的一部分被調(diào)用。在數(shù)據(jù)庫第一次被打開時或者當(dāng)指定的版本號高于當(dāng)前被持久化的數(shù)據(jù)庫的版本號時,這個 versionchange 事務(wù)將被創(chuàng)建。onupgradeneeded 是我們唯一可以修改數(shù)據(jù)庫結(jié)構(gòu)的地方。在這里面,我們可以創(chuàng)建和刪除對象存儲空間以及構(gòu)建和刪除索引。
2、構(gòu)建數(shù)據(jù)庫IndexedDB 使用對象存儲空間而不是表,并且一個多帶帶的數(shù)據(jù)庫可以包含任意數(shù)量的對象存儲空間。每當(dāng)一個值被存儲進(jìn)一個對象存儲空間時,它會被和一個鍵相關(guān)聯(lián)。
// 數(shù)據(jù)庫首次創(chuàng)建版本,或者window.indexedDB.open傳遞的新版本(版本數(shù)值要比現(xiàn)在的高) request.onupgradeneeded = function (event) { //之前咱們不是在success中得到了db了么,為什么還要在這獲取, //因為在當(dāng)前事件函數(shù)執(zhí)行后才會去執(zhí)行success事件 var db = event.target.result; // 創(chuàng)建一個對象存儲空間,keyPath是id,keyGenerator是自增的 var objectStore = db.createObjectStore("testItem",{keyPath: "id",autoIncrement: true}); // 創(chuàng)建一個索引來通過id搜索,id是自增的,不會有重復(fù),所以可以用唯一索引 objectStore.createIndex("id","id",{unique: true}) objectStore.createIndex("name","name"); objectStore.createIndex("age","age"); //添加一條信息道數(shù)據(jù)庫中 objectStore.add({name: "cfangxu", age: "27"}); }
注意: 執(zhí)行完后,在調(diào)試工具欄Application的indexedDB中也看不到,你得右鍵刷新一下。
創(chuàng)建索引的語法:
objectStore.createIndex(indexName, keyPath, objectParameters) indexName:創(chuàng)建的索引名稱,可以使用空名稱作為索引。 keyPath:索引使用的關(guān)鍵路徑,可以使用空的keyPath, 或者keyPath傳為數(shù)組keyPath也是可以的。 objectParameters:可選參數(shù)。常用參數(shù)之一是unique,表示該字段值是否唯一,不能重復(fù)。例如,本demo中id是不能重復(fù)的,于是有設(shè)置:3、添加數(shù)據(jù)
上面的代碼建好了字段,并且添加了一條數(shù)據(jù),但是我們?nèi)绻朐趏nupgradeneeded事件外面操作,接下來的步驟了。
由于數(shù)據(jù)庫的操作都是基于事務(wù)(transaction)來進(jìn)行,于是,無論是添加編輯還是刪除數(shù)據(jù)庫,我們都要先建立一個事務(wù)(transaction),然后才能繼續(xù)下面的操作。
語法: var transaction = db.transaction(dbName, "readwrite");
第一個參數(shù)是事務(wù)希望跨越的對象存儲空間的列表,可以是數(shù)組或者字符串。如果你希望事務(wù)能夠跨越所有的對象存儲空間你可以傳入一個空數(shù)組。如果你沒有為第二個參數(shù)指定任何內(nèi)容,你得到的是只讀事務(wù)。因為這里我們是想要寫入所以我們需要傳入 "readwrite" 標(biāo)識。
var timer = setInterval(function () { if(db) { clearInterval(timer); // 新建一個事務(wù) var transaction = db.transaction(["testItem"], "readwrite"); // 打開一個存儲對象 var objectStore = transaction.objectStore("testItem"); // 添加數(shù)據(jù)到對象中 objectStore.add({ name: "xiaoming", age: "12" }); objectStore.add({ name: "xiaolong", age: "20" }); } },100)
為什么要用一個間隔定時器? 因為這是一個demo,正常的是要有操作才能進(jìn)行數(shù)據(jù)庫的寫入,在我們的demo中,js執(zhí)行到transaction會比indexedDB的onsuccess事件回調(diào)快,導(dǎo)致會拿到db為undefined,所以寫了個間隔定時器等它一會。
4、獲取數(shù)據(jù)var transaction = db.transaction(["testItem"], "readwrite"); var objectStore = transaction.objectStore("testItem"); var getRquest = objectStore.get(1); getRquest.onsuccess = function (event) { console.log(getRquest.result); } //輸出:{name: "cfangxu", age: "27", id: 1}5、修改數(shù)據(jù)
var transaction = db.transaction(["testItem"], "readwrite"); var objectStore = transaction.objectStore("testItem"); var getRquest = objectStore.put({ name: "chenfangxu", age: "27", id:1 }); // 修改了id為1的那條數(shù)據(jù)6、刪除數(shù)據(jù)
var transaction = db.transaction(["testItem"], "readwrite"); var objectStore = transaction.objectStore("testItem"); var getRquest = objectStore.delete(1); // 刪除了id為1的那條數(shù)據(jù)
上面的例子執(zhí)行完后,一定一定要右鍵刷新indexedDB,它自己是不會變的。
關(guān)于數(shù)據(jù)庫的名詞解釋和indexedDB的游標(biāo)介紹參閱:HTML5 indexedDB前端本地存儲數(shù)據(jù)庫實例教程 張大神的文中沒有指出新手要踩的坑,我踩完也說明了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90424.html
摘要:該模塊實現(xiàn)方案主要包含與這兩個關(guān)鍵字,其允許某個模塊對外暴露部分接口并且由其他模塊導(dǎo)入使用。由于在服務(wù)端的流行,的模塊形式被不正確地稱為。以上所描述的模塊載入機(jī)制均定義在中。 最近一直在搞基礎(chǔ)的東西,弄了一個持續(xù)更新的github筆記,可以去看看,誠意之作(本來就是寫給自己看的……)鏈接地址:Front-End-Basics 此篇文章的地址:JavaScript的模塊 基礎(chǔ)筆記...
摘要:我的書簽我的書簽謹(jǐn)慎導(dǎo)入,小心覆蓋工具類版本管理快速切換源配置教程指南可視化工具前端工具集前端助手網(wǎng)絡(luò)封包截取工具格式化工具標(biāo)注工具模擬請求類深入淺出布局你所不知道的動畫技巧與細(xì)節(jié)常用代碼黑魔法小技巧,讓你少寫不必要的,代碼更優(yōu)雅一勞永 我的書簽 我的書簽(謹(jǐn)慎導(dǎo)入,小心覆蓋) 工具類 nvm: node版本管理 nrm: 快速切換npm源 shell: zsh+on-my-zsh配...
摘要:我的書簽我的書簽謹(jǐn)慎導(dǎo)入,小心覆蓋工具類版本管理快速切換源配置教程指南可視化工具前端工具集前端助手網(wǎng)絡(luò)封包截取工具格式化工具標(biāo)注工具模擬請求類深入淺出布局你所不知道的動畫技巧與細(xì)節(jié)常用代碼黑魔法小技巧,讓你少寫不必要的,代碼更優(yōu)雅一勞永 我的書簽 我的書簽(謹(jǐn)慎導(dǎo)入,小心覆蓋) 工具類 nvm: node版本管理 nrm: 快速切換npm源 shell: zsh+on-my-zsh配...
摘要:小弟在前端摸爬滾打一段時間,發(fā)現(xiàn)前端的比較好的文檔比較分散,特別是中文的,我平時都是收藏在瀏覽器里,以后有好的教程和綜合性的文檔我會更新到這里。小組中文文檔,很全。 小弟在前端摸爬滾打一段時間,發(fā)現(xiàn)前端的比較好的文檔比較分散,特別是中文的,我平時都是ctrl+D收藏在瀏覽器里,以后有好的教程和綜合性的文檔我會更新到這里。一則可以做個記錄,防止丟失。二則有需要的朋友可以來我這里找一找。 ...
閱讀 2630·2021-11-17 09:33
閱讀 4015·2021-10-19 11:46
閱讀 945·2021-10-14 09:42
閱讀 2291·2021-09-22 15:41
閱讀 4288·2021-09-22 15:20
閱讀 4683·2021-09-07 10:22
閱讀 2346·2021-09-04 16:40
閱讀 842·2019-08-30 15:52