成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識庫 > 如何使用localstorage代替cookie實(shí)現(xiàn)跨域共享數(shù)據(jù)問題

如何使用localstorage代替cookie實(shí)現(xiàn)跨域共享數(shù)據(jù)問題

熱門標(biāo)簽:濟(jì)南辦理400電話 鶴壁手機(jī)自動外呼系統(tǒng)怎么安裝 ai電銷機(jī)器人連接網(wǎng)關(guān) 鄭州電銷外呼系統(tǒng)違法嗎 威海營銷外呼系統(tǒng)招商 漳州人工外呼系統(tǒng)排名 中紳電銷智能機(jī)器人 跟電銷機(jī)器人做同事 農(nóng)村住宅地圖標(biāo)注

一,背景

 

因?yàn)榫W(wǎng)站系統(tǒng)的日益龐大,不同域名業(yè)務(wù),甚至不同合作方網(wǎng)站的cookie可能或多或少需要進(jìn)行共享使用,遇到這個(gè)情況的時(shí)候,大家一般想到的是使用登錄中心分發(fā)cookie狀態(tài)再進(jìn)行同步進(jìn)行解決,成本較高而且實(shí)施起來比較復(fù)雜和麻煩。

因?yàn)閏ookie在跨域的情況下,瀏覽器根本不允許互相訪問的限制,為了突破這個(gè)限制,所以有了以下這個(gè)實(shí)現(xiàn)方案,使用postmessage和localstorage進(jìn)行數(shù)據(jù)跨域共享。

原理比較簡單,但是遇到的坑也不少,這里梳理一下,做個(gè)備份。

二,API設(shè)計(jì)

背景中說過我們使用localstorage來代替cookie,本身localstorage和cookie就有一些使用上的區(qū)別,比如localstorage的容量更大,但是不存在過期時(shí)間,雖然容量大,但在不同的瀏覽器上也都有空間上限,操作不好很容易崩潰,還有就是postmessage雖然支持跨域,安全問題和api的異步化也給使用帶來了一些麻煩,我們?nèi)绾伟堰@個(gè)模塊設(shè)計(jì)的更易用呢?

先看下我設(shè)計(jì)的API:

import { crosData } from 'base-tools-crossDomainData';
var store = new crosData({
    iframeUrl:"somefile.html", //共享iframe地址,iframe有特殊要求,詳見模板文件    
    expire:'d,h,s' //單位天,小時(shí),秒 默認(rèn)過期時(shí)間,也可以種的時(shí)候覆蓋
});
store.set('key','val',{
    expire:'d,h,s' //option 可帶過期時(shí)間,覆蓋expire
}).then((data)=>{
    //異步方法,如果種失敗,會進(jìn)入catch事件
    //data {val:'val',key:'key',domain:'domain'};
}).catch((err)=>{
    console.log(err);
}); 
store.get('key',{
    domain:'(.*).sina.cn' //可以指定域名,也可以使用(.*)來匹配正則字符串,返回的val信息會帶著domain信息,不填寫則返回本域的
}).then((vals)=>{
    console.log(val) //異步獲取存儲數(shù)據(jù),可能多個(gè),是個(gè)數(shù)組 [{},{}]
}).catch((err)=>{
});
store.clear('key').then().catch(); //只清楚當(dāng)前域下的key,不允許清除其他域下的key,只能讀

一個(gè)模塊上手快不快主要看api,所以對于一個(gè)數(shù)據(jù)共享模塊,我認(rèn)為支持set,get,clear這3個(gè)方法就ok了,因?yàn)閜ostmessage本身是個(gè)一來一回的異步的行為,包裝成promise的肯定更為合適和易用。因?yàn)閘ocalstorage不支持過期時(shí)間,所以需要一個(gè)全局的過期時(shí)間配置,當(dāng)然也可以在set的時(shí)候進(jìn)行單獨(dú)配置,而get的時(shí)候我們可以指定獲取某個(gè)域下的數(shù)據(jù)或者多個(gè)域下的數(shù)據(jù),因?yàn)閗ey名可能重復(fù),但是域只有一個(gè)。這里就牽扯到了數(shù)據(jù)的管理,后邊單獨(dú)來說,最后clear和set的api只能種本域的數(shù)據(jù),不可以操作其他域下的數(shù)據(jù),get被允許。

下面我們看一下,client端的設(shè)置和API:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>crosData</title> 
    </head>
    <body>
        <script>
            window.CROS = {
                domain:/(.*).sina.cn/, //或者你允許的域名,支持正則和*通配符
                lz:false //是否開啟lz壓縮val字符
            };
        </script>
        <script src="http://cdn/sdk.js"></script>
    </body>
</html>

你可以靈活在任何一個(gè)域下的一個(gè)html文檔中,引入client的js sdk,然后通過全局屬性的方式配置一個(gè)你允許被種到這個(gè)文檔所在域下的domain白名單,支持正則,然后lz是是否啟動lz-string壓縮,至于什么是lz壓縮后邊我再介紹。

到這里,一個(gè)比較通用的API設(shè)計(jì)就完成了,下面我們看一下實(shí)現(xiàn)原理和具體的一些問題。

三,實(shí)現(xiàn)原理

說起來好想蠻簡單的,但是寫起來其實(shí)并不是,我們首先需要知道postMessage怎么用,這個(gè)屬于很常見的一個(gè)API了,他有一個(gè)要點(diǎn)這里告訴大家,就是postMessage只能在iframe中或者使用window.open這種開啟新頁面的方式進(jìn)行互相通訊,當(dāng)然這里我們首先就要創(chuàng)建一個(gè)隱藏的iframe,進(jìn)行跨域。

 

懶得拿工具畫圖了,因?yàn)榱鞒瘫容^清晰,這里拿文字復(fù)述一下整個(gè)通訊流程,首先父頁面創(chuàng)建一個(gè)隱藏的iframe,然后當(dāng)執(zhí)行set,get,clear等command的時(shí)候,通過postMessage來進(jìn)行消息廣播,子頁面接收到消息后,解析命令,數(shù)據(jù)和回調(diào)id(postMessage無法傳遞函數(shù)和引用,兼容問題導(dǎo)致,最好只傳string類型,所以還需要對data做stringify)。然后當(dāng)子頁面處理完localstorage的操作后,再通過postMessage把對應(yīng)的cbid和data返回給父頁面,父頁面監(jiān)聽message事件,處理結(jié)果。

四,編碼

嗯,所以說沒幾行,我們下面開始進(jìn)行編碼了:

首先介紹一下我們用到的第三方包都有什么,為什么要用:

1,url-parse 對url進(jìn)行parse解析,主要用他里面的origin屬性,因?yàn)閜ostMessage本身對origin就有嚴(yán)格的驗(yàn)證,我們要支持白名單和域名管理也需要。

2,ms 對時(shí)間簡寫做毫秒轉(zhuǎn)換的工具庫。

3, lz-string 對字符串做壓縮用的工具包,這里給大家科普一下LZ壓縮算法,首先了解LZ需要先了解RLZ,Run Length Encoding ,是一個(gè)針對無損壓縮的非常簡單的算法。它用重復(fù)字節(jié)和重復(fù)的次數(shù)來簡單描述來代替重復(fù)的字節(jié)。LZ 壓縮算法的背后是使用 RLE 算法用先前出現(xiàn)的相同字節(jié)序列的引用來替代。簡單的講, LZ 算法被認(rèn)為是字符串匹配的算法。例如:在一段文本中某字符串經(jīng)常出現(xiàn),并且可以通過前面文本中出現(xiàn)的字符串指針來表示。

lz-string本身有優(yōu)勢就是可以大大的減小你的儲存量,本身5MB的localstorage如果用來支持多域名的數(shù)據(jù)保存,很快就會被壓縮用完,但是lz-string本身比較慢,消耗比較大,大家平時(shí)在工作中如果對傳輸數(shù)據(jù)量有大小要求的話可以嘗試使用這個(gè)壓縮算法來優(yōu)化字符串長度,默認(rèn)是不開啟的。

4,store2 本身localstorage的api比較簡陋,為了減少代碼邏輯復(fù)雜度,這里選了一個(gè)比較流行的localstorage的實(shí)現(xiàn)庫來進(jìn)行store的操作。

說完了第三方包我們下面看一下父頁面的js怎么來寫:

class crosData {
  constructor(options) {
    supportCheck();
    this.options = Object.assign({
      iframeUrl: '',
      expire: '30d'
    }, options);
    this.cid = 0;
    this.cbs = {};
    this.iframeBeforeFuns = [];
    this.parent = window;
    this.origin = new url(this.options.iframeUrl).origin;
    this.createIframe(this.options.iframeUrl);
    addEvent(this.parent, 'message', (evt) => {
      var data = JSON.parse(evt.data);
      var origin = evt.origin || evt.originalEvent.origin;
      //我只接收我打開的這個(gè)iframe的message,其他的都是不合法的,直接報(bào)錯
      if (origin !== this.origin) {
        reject('illegal origin!');
        return;
      }
      if (data.err) {
        this.cbs[data.cbid].reject(data.err);
      } else {
        this.cbs[data.cbid].resolve(data.ret);
      }
      delete this.cbs[data.cbid];
    });
  }
  createIframe(url) {
    addEvent(document, 'domready', () => {
      var frame = document.createElement('iframe');
      frame.style.cssText = 'width:1px;height:1px;border:0;position:absolute;left:-9999px;top:-9999px;';
      frame.setAttribute('src', url);
      frame.onload = () => {
        this.child = frame.contentWindow;
        this.iframeBeforeFuns.forEach(item => item());
      }
      document.body.appendChild(frame);
    });
  }
  postHandle(type, args) {
    return new Promise((resolve, reject) => {
      var cbid = this.cid;
      var message = {
        cbid: cbid,
        origin: new url(location.href).origin,
        action: type,
        args: args
      }
      this.child.postMessage(JSON.stringify(message), this.origin);
      this.cbs[cbid] = {
        resolve,
        reject
      }
      this.cid++;
    });
  }
  send(type, args) {
    return new Promise(resolve => {
      if (this.child) {
        return this.postHandle(type, args).then(resolve);
      } else {
        var self = this;
        this.iframeBeforeFuns.push(function() {
          self.postHandle(type, args).then(resolve);
        });
      }
    })
  }
  set(key, val, options) {
    options = Object.assign({
      expire: ms(this.options.expire)
    }, options);
    return this.send('set', [key, val, options]);
  }
  get(key, options) {
    options = Object.assign({
      domain: new url(location.href).origin
    }, options);
    return this.send('get', [key, options]);
  }
  clear(key) {
    return this.send('clear', [key]);
  }
}

大概方法就這么幾個(gè),這里有幾個(gè)關(guān)鍵點(diǎn),我說一下。

1,get,set,clear方法都是統(tǒng)一的調(diào)用的send方法,只不過對options部分做了補(bǔ)齊。

2,send方法返回一個(gè)promise對象,如果iframe已經(jīng)onload成功,則直接調(diào)用postHandle方法進(jìn)行postMessage操作,如果iframe還在加載中,則把當(dāng)前的操作推到iframeBeforeFuns數(shù)組中,用函數(shù)包裹,等待iframe onload結(jié)束后統(tǒng)一調(diào)用,函數(shù)包裹的也是postHandle方法。

3,postHandle方法,在發(fā)送請求前包裝data,生成cbid,origin,action和args,cbs對象保存了每個(gè)cbid下的resolve和reject,等待子頁面的postMessage返回后處理。因?yàn)閜ostMessage不能保留引用,不能傳函數(shù),所以這里選擇這個(gè)方法來進(jìn)行關(guān)聯(lián)。

4,constructor比較好理解,當(dāng)這個(gè)類被初始化的時(shí)候,我們定義了我們需要的一些options的屬性,創(chuàng)建iframe,然后監(jiān)聽message事件,處理子頁面返回的消息。

5,在父頁面的message事件中,我們要校驗(yàn),給我發(fā)消息的必須是我打開的這個(gè)窗口iframe,否則報(bào)錯,然后根據(jù)data中的err標(biāo)識來讓cbs中的resolve和reject進(jìn)行執(zhí)行。

6,createIframe方法中,iframe onload中的回調(diào)處理創(chuàng)建前 緩存的調(diào)用方法,這里注意使用了domready,因?yàn)榭赡躡ody還沒解析就會進(jìn)行sdk的執(zhí)行。

下面是child部分的代碼:

class iframe {
  set(key, val, options, origin) {
    //檢查val大小,不能超過20k.
    val = val.toString();
    val = this.lz ? lzstring.compressToUTF16(val) : val;
    var valsize = sizeof(val, 'utf16'); //localStorage 儲存使用utf16編碼計(jì)算字節(jié)
    if (valsize > this.maxsize) {
      return {
        err: 'your store value : "' + valstr + '" size is ' + valsize + 'b, maxsize :' + this.maxsize + 'b , use utf16'
      }
    }
    key = `${this.prefix}_${key},${new url(origin).origin}`;
    var data = {
      val: val,
      lasttime: Date.now(),
      expire: Date.now() + options.expire
    };
    store.set(key, data);
    //大于最大儲存?zhèn)€數(shù),刪除最后一次更新的
    if (store.size() > this.storemax) {
      var keys = store.keys();
      keys = keys.sort((a, b) => {
        var item1 = store.get(a),
          item2 = store.get(b);
        return item2.lasttime - item1.lasttime;
      });
      var removesize = Math.abs(this.storemax - store.size());
      while (removesize) {
        store.remove(keys.pop());
        removesize--;
      }
    }
    return {
      ret: data
    }
  }
  get(key, options) {
    var message = {};
    var keys = store.keys();
    var regexp = new RegExp('^' + this.prefix + '_' + key + ',' + options.domain + '$');
    message.ret = keys.filter((key) => {
      return regexp.test(key);
    }).map((storeKey) => {
      var data = store.get(storeKey);
      data.key = key;
      data.domain = storeKey.split(',')[1];
      if (data.expire < Date.now()) {
        store.remove(storeKey);
        return undefined;
      } else {
        //更新lasttime;
        store.set(storeKey, {
          val: data.val,
          lasttime: Date.now(),
          expire: data.expire
        });
      }
      data.val = this.lz ? lzstring.decompressFromUTF16(data.val) : data.val;
      return data;
    }).filter(item => {
      return !!item; //過濾undefined
    });
    return message;
  }
  clear(key, origin) {
    store.remove(`${this.prefix}_${key},${origin}`);
    return {};
  }
  clearOtherKey() {
    //刪除不合法的key 
    var keys = store.keys();
    var keyReg = new RegExp('^' + this.prefix);
    keys.forEach(key => {
      if (!keyReg.test(key)) {
        store.remove(key);
      }
    });
  }
  constructor(safeDomain, lz) {
    supportCheck();
    this.safeDomain = safeDomain || /.*/;
    this.prefix = '_cros';
    this.clearOtherKey();
    if (Object.prototype.toString.call(this.safeDomain) !== '[object RegExp]') {
      throw new Error('safeDomain must be regexp');
    }
    this.lz = lz;
    this.storemax = 100;
    this.maxsize = 20 * 1024; //字節(jié)
    addEvent(window, 'message', (evt) => {
      var data = JSON.parse(evt.data);
      var originHostName = new url(evt.origin).hostname;
      var origin = evt.origin,
        action = data.action,
        cbid = data.cbid,
        args = data.args;
      //合法的廣播
      if (evt.origin === data.origin && this.safeDomain.test(originHostName)) {
        args.push(origin);
        var whiteAction = ['set', 'get', 'clear'];
        if (whiteAction.indexOf(action) > -1) {
          var message = this[action].apply(this, args);
          message.cbid = cbid;
          window.top.postMessage(JSON.stringify(message), origin);
        }
      } else {
        window.top.postMessage(JSON.stringify({
          cbid: cbid,
          err: 'Illegal domain'
        }), origin);
      }
    });
  }
}

代碼也不多,這里簡單說一下各個(gè)方法的用處和組織關(guān)系:

1,constructor部分,上面的類里也進(jìn)行瀏覽器特性支持檢查,然后定義了store的prefix值,最大個(gè)數(shù)和每一個(gè)key的maxsize等屬性。然后我們創(chuàng)建message通道,等待父頁面調(diào)用。

2,在message中,我們對發(fā)送廣播的origin進(jìn)行檢查,然后對調(diào)用的方法進(jìn)行檢查,調(diào)用對應(yīng)的set,get,clear方法,然后把執(zhí)行的結(jié)果拿到,綁定cbid,最后再postMessage發(fā)送回父頁面。

3,clearOtherKey 刪除不合法的一些store數(shù)據(jù),只保留符合格式的數(shù)據(jù)。

4,set方法中對每一條的數(shù)據(jù)做size校驗(yàn),lz壓縮,保存的data中包含了val,key,過期時(shí)間以及更新時(shí)間(用于LRU計(jì)算)。

5,set方法中,如果儲存的ls個(gè)數(shù)超過了最大限制,這個(gè)時(shí)候需要進(jìn)行刪除操作, LRU是Least Recently Used的縮寫,即最近最少使用。我們通過遍歷所有的key值,對key值做一個(gè)排序,通過lasttime,然后進(jìn)行keys數(shù)組的pop操作,拿到堆棧尾部的需要被清除的key,然后逐個(gè)刪除。

6,get方法中,我們通過遍歷所有的key值,匹配到我們需要拿到的domain的域的key,然后把返回值中的key進(jìn)行拆解(我們儲存時(shí)是 key,domain的格式),因?yàn)閍pi要求返回多個(gè)符合的值,我們對過期的數(shù)據(jù)最后再做一個(gè)filter,然后使用lz解壓縮val值,保證用戶拿到的是正確結(jié)果。

以上就是我們的一個(gè)整體實(shí)現(xiàn)編碼過程和review,下面說一說遇到的坑。

五,一些遇到的坑

因?yàn)樯厦嬷唤o了主代碼,并不是完整代碼,因?yàn)楸旧磉壿嫳容^清晰,花一點(diǎn)時(shí)間都可以寫出來的。下面說說有什么坑的地方。

1,計(jì)算localstorage的儲存值。

因?yàn)槲覀兌贾烙?MB的限制,所以每一條數(shù)據(jù)最大要求不能超過20*1024 字節(jié),對于字節(jié)的計(jì)算,localstorage要使用utf16的編碼進(jìn)行轉(zhuǎn)換,參考這篇文章: JS計(jì)算字符串所占字節(jié)數(shù)

2,兼容性

ie8下postMessage最好都傳字符串,事件需要抹平處理,JSON需要抹平處理。

3,創(chuàng)建iframe時(shí)的異步處理

這里之前做了個(gè)一個(gè)setTimeout的遞歸等待,后來更改成了上面的實(shí)現(xiàn)方法,通過onload后統(tǒng)一處理promise的reslove,保證promise api的統(tǒng)一。

4,數(shù)據(jù)保存時(shí),空間復(fù)雜度 vs 時(shí)間復(fù)雜度。

第一個(gè)版本并不是上面的實(shí)現(xiàn),我實(shí)現(xiàn)了3個(gè)版本:

第一個(gè)版本是保存了一個(gè)LRU的數(shù)組,為了減少時(shí)間復(fù)雜度,但是浪費(fèi)了空間復(fù)雜度,而且經(jīng)過測試,store的get方法耗時(shí)比較大,主要是parse的耗時(shí)。

第二個(gè)版本,為了能讓lz-string壓縮率最大化,我把所有的數(shù)據(jù)包括LRU數(shù)組保存到了一個(gè)key值上,導(dǎo)致數(shù)據(jù)多的時(shí)候lz-string和getItem,parse時(shí)間消耗非常大,雖然計(jì)算的時(shí)間復(fù)雜度是最低。

最后一個(gè)版本,就是上面的,我犧牲了一些時(shí)間復(fù)雜度和空間復(fù)雜度,但是因?yàn)槠款i在于set和get的讀寫速度,單個(gè)的保存讀寫速度極快,獲取keys的方法因?yàn)榈讓邮怯玫膄or in localstorage實(shí)現(xiàn)的,性能還是很不錯的,20kb存滿100條,讀寫也在1s左右,性能非常不錯。

六,總結(jié)和對比

模塊寫完了,我才知道原來還有這么一個(gè)庫: zendesk/cross-storage

但是我查看了他的api和源代碼,對比了一下實(shí)現(xiàn)方法,我覺得還是我這個(gè)版本考慮的比較多。

1,我的版本對域名和數(shù)據(jù)的管理有控制。

2,我的版本promise api更簡化,比它少一個(gè)onConnect,可以參考他的實(shí)現(xiàn),比我寫的多多了,也沒解決這個(gè)iframe等待異步的問題。

3,不支持lz壓縮數(shù)據(jù)。

4,不支持LRU的儲存池管理,所以可能存多了造成寫不進(jìn)的問題。

5,他貌似每次交互都搞一個(gè)iframe,太浪費(fèi)dom操作和廣播了,我覺得一直開著并沒有什么問題,當(dāng)然他可能有需求連接多個(gè)client才這么處理的。

總結(jié)

以上所述是小編給大家介紹的使用localstorage代替cookie實(shí)現(xiàn)跨域共享數(shù)據(jù)問題,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

標(biāo)簽:營口 蘇州 萍鄉(xiāng) 惠州 紅河 咸陽 文山 甘南

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《如何使用localstorage代替cookie實(shí)現(xiàn)跨域共享數(shù)據(jù)問題》,本文關(guān)鍵詞  如何,使用,localstorage,代替,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《如何使用localstorage代替cookie實(shí)現(xiàn)跨域共享數(shù)據(jù)問題》相關(guān)的同類信息!
  • 本頁收集關(guān)于如何使用localstorage代替cookie實(shí)現(xiàn)跨域共享數(shù)據(jù)問題的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    国产亚洲精品综合一区91| 蜜臀在线观看| 麻豆传媒在线播放| 亚洲视频一区二区在线| 国产成人一区二区| 天堂av中文字幕| 国产成+人+日韩+欧美+亚洲| 136国产福利精品导航| 手机在线不卡av| 久久精品国产综合| 日韩尤物视频| 又骚又黄的视频| 国产精品欧美一区二区三区奶水| 日本韩国欧美在线| av成人激情| 亚洲欧洲视频在线观看| 无码人妻丰满熟妇啪啪欧美| 亚洲精品网址在线观看| 全部免费毛片在线播放一个| 人人狠狠综合久久亚洲| 婷婷开心激情综合| 国产精品一区二区黑丝| 亚洲国产日日夜夜| 全亚洲最色的网站在线观看| 天天操天天摸天天干| 在线欧美日韩国产| 国产91精品久久久久| 日韩国产在线观看| 免费在线看黄色片| 国产资源在线播放| 亚洲老女人av| 久久综合给合久久狠狠狠97色69| 欧美最猛黑人xxxx| 蜜桃av噜噜一区二区三区| bdsm在线观看播放视频| 999国产精品一区| 成人免费毛片app| 国产一级片大全| 成人综合国产精品| 青草视频在线观看视频| 国产乱人伦精品一区二区| 国产无套内射久久久国产| 中文字幕av一区二区三区| 免费视频网站www| 久久久久亚洲AV成人| 精品久久中文字幕| 国产极品jizzhd欧美| 国产一区二区久久久久| 可以直接看的黄色网址| 久久精品国产91精品亚洲| 欧美寡妇性猛交xxx免费| 久久亚洲图片| 欧美成人精品欧美一级乱| 可以免费看污视频的网站在线| 一二三四社区在线视频6| 国产另类自拍| 欧洲成人在线观看| 国产精品久久9| 久久色.com| 国产伦一区二区三区色一情| 久久久久久91精品色婷婷| 四虎精品欧美一区二区免费| 欧美日韩福利视频| 麻豆视频观看网址久久| 成人3d动漫网站| 久草在线资源站手机版| 色婷婷综合成人| 尤蜜粉嫩av国产一区二区三区| 8x8x最新地址| 盗摄牛牛av影视一区二区| 在线看的片片片免费| 毛片在线网址| 亚洲 欧美 日韩 综合| 亚洲小说区图片区都市| 欧美一级高清免费播放| 午夜视频在线观| 伊人天天久久大香线蕉av色| 日本按摩中出| 青青草免费在线视频| 久久电影网电视剧免费观看| 欧美丰满熟妇bbb久久久| 欧美xxxx18国产| 久操视频免费在线观看| 黑人巨大40cm重口| 国产曰肥老太婆无遮挡| 国产成人av一区二区三区在线| 亚欧精品一区二区三区| 久久精品无码一区二区三区| 国产私拍精品| 加勒比综合在线| 成人涩涩免费视频| 国产色综合久久| 久久久久久久影视| 国产精品成人无码专区| 男人晚上看的视频| 蜜桃av综合| 日韩有吗在线观看| 日日摸夜夜夜夜夜添| 欧美日韩高清在线播放| 欧美日韩国产在线| 日韩一级免费一区| 日本黄色免费在线观看| 国产一区三区三区| 久久嫩草精品久久久精品| 老司机精品免费视频| 欧美激情精品久久| 一区二区三区视频在线观看免费| 国产亚洲欧美精品久久久www| 亚洲国产天堂久久国产91| 性xxxxfjsxxxxx欧美| 93在线视频精品免费观看| 欧美日韩国产高清视频| 国产激情视频一区| 亚洲午夜视频| 国产一级在线观看| 免费观看成人毛片| 成人午夜视频免费观看| 88av在线| 国产精品后入内射日本在线观看| 日本一区二区免费在线观看| 国产精品久久久久久久久久久久久久久久久久| 国产欧美一区在线| 91超碰免费在线| 1024视频在线| 亚洲夂夂婷婷色拍ww47| 亚洲人成影院在线| 黄污网站在线观看| 99精品国产一区二区三区不卡| 婷婷激情小说网| 久久婷婷一区二区| 国产精品秘入口| gogo大尺度成人免费视频| 亚洲一区二区三区中文字幕在线观看| 蜜桃传媒一区二区亚洲av| 国产欧美一区二区精品久导航| 色老板视频在线观看| 日韩一区二区三区在线观看视频| 欧美视频xxx| 欧美日韩电影一区| 日韩免费av片在线观看| 粉嫩欧美一区二区三区| 欧美另类69xxx| 成人黄色电影网址| 色偷偷福利视频| 91成人在线免费| h片视频在线观看| 四虎成人精品在永久免费| 国产福利免费视频| 99在线影院| 欧美视频二区欧美影视| 国产视频99| 色猫咪免费人成网站在线观看| 亚洲成人av福利| 久久毛片高清国产| 国产在线精品一区免费香蕉| 欧洲亚洲精品视频| 91无套直看片红桃在线观看| 国色天香一二三期区别大象| 91久久人澡人人添人人爽欧美| 日韩高清不卡一区二区| 精品动漫一区二区三区在线观看| 国产精品视频区| 51精品久久久久久久蜜臀| 日韩中文一区二区三区| 午夜精品一二三区| 国产一区av在线| 亚洲男人电影天堂| www视频完整版| 久久精品一二三四| 97超碰在线资源| 成人在线视频免费| 性娇小13――14欧美| 偷拍中文亚洲欧美动漫| 国产精品第三页| 国产suv精品一区二区三区88区| 中文字幕一区二区三区免费视频| 国产99久久精品一区二区永久免费| www.日韩.com| 人妻中文字幕一区| 国产成人在线网站| 草b视频在线观看| 国产欧美日韩专区| 国产午夜福利在线播放| 国产精品福利视频一区二区三区| 中文字幕一区二区三区四区五区六区| xvideos国产在线视频| 在线观看av黄网站永久| 中文精品视频一区二区在线观看| 国产伦精品一区二区三区88av| 亚洲国产精品va在线看黑人动漫| 99热在线这里只有精品| jizzjizzjizz美国| 黄网站免费看| 麻豆国产精品777777在线| 国产九色视频| 国产精品国产馆在线真实露脸| 99久久99精品久久久久久| 亚洲无码精品国产| 欧美一级片在线观看| 亚洲欧美日韩精品永久在线| 欧美大片在线看免费观看| 日本一道在线观看| 伊人精品一区二区三区| 伊人网在线免费观看| 欧美体内谢she精2性欧美| 欧美三级视频在线| 日本激情一区二区三区| ...av二区三区久久精品| 亚洲国产成人91精品| 中文字幕第八页| 免费在线观看羞羞视频| 精品久久99| 亚洲图片小说网| 亚洲精品自拍动漫在线| 久久伊人精品视频| 亚洲最大激情中文字幕| 日韩精品极品视频免费观看| 日韩av高清在线看片| 日韩视频免费观看高清在线视频| 亚洲精品99| 91se在线观看| 熟妇人妻无乱码中文字幕真矢织江| 国产91精品欧美| 麻豆视频在线看| 日本欧洲国产一区二区| 日本在线视频中文字幕| 91caoporm在线视频| 久久狠狠一本精品综合网| wwww在线观看免费视频| 这里只有精品免费视频| 欧美v日韩v国产v| 黄瓜视频免费观看在线观看www| 亚洲精品婷婷| av资源一区| 男女小视频在线观看| 欧美人与物videos另类xxxxx| 天天插天天射天天干| 日本一二三不卡视频| 三级网站在线免费观看| 超碰国产在线观看| 久久99青青| 麻豆传媒网站在线观看| 黄色在线免费观看网站| 黑人中文字幕一区二区三区| 中文字幕网站视频在线| 欧美色图亚洲图片| 青青草娱乐在线| 久久亚洲av午夜福利精品一区| 性xxxx欧美老肥妇牲乱| 国产成人激情视频| 日韩欧美第一页| 亚洲人成网站在线播| 国产欧美日韩亚洲一区二区三区| 免费成人av网站| 日韩欧美三级电影| 中文字幕观看av| 久久国产精品精品国产色婷婷| 麻豆网站视频在线观看| 中出福利视频| 国产第一页浮力| 日韩欧美中文| 国产福利久久精品| 亚洲人成网站精品片在线观看| 国产露脸91国语对白| 国产精美视频| 偷拍日韩校园综合在线| 天堂а√在线中文在线鲁大师| 日韩欧美在线观看一区二区| 国产免费一区二区三区在线能观看| 风韵丰满熟妇啪啪区老熟熟女| 91在线视频观看| 国产人妻777人伦精品hd| 亚洲一区二区精品久久av| 91免费观看在线| 天天色天天草天天射| 成年人深夜福利| 日韩在线不卡一区| 亚洲美女啪啪| 国产视频2区| 欧美在线网站| 亚洲精品一区二区三区精华液| 国产精品午夜春色av| 亚洲系列在线观看| 国产精品一区二区免费| 成人黄色在线观看视频| 亚洲色图 校园春色| 亚洲最大成人网站| 国产一区国产二区国产三区| 国产一区二区精品久| 日本不卡一区| 最新av网址在线观看| 日韩美女视频中文字幕| 精品无人区乱码1区2区3区在线| www久久日com| 伊人久久大香线蕉综合75| 夜夜春亚洲嫩草影视日日摸夜夜添夜| 日本亚洲最大的色成网站www| 精品视频偷偷看在线观看| 亚洲天堂中文字幕在线| 欧美精品videos| 欧美韩日精品| 色偷偷偷在线视频播放| 午夜国产福利一区二区| 久久综合亚洲| 国产伦精品一区二区三区视频| 调教+趴+乳夹+国产+精品| 久久99精品久久久久| 91精品国产色综合久久不卡98口| 日韩欧美亚洲成人| 日韩手机在线导航| 欧美v亚洲v综合v国产v仙踪林| 久久亚洲资源| 国产字幕在线观看| 国产欧美日本一区二区三区| 国产精品理论片在线观看| 波多野结衣黄色网址| 国精产品一区一区三区mba下载| 中文字幕网站在线观看| www.4hu95.com四虎| 国产亚洲精品久久久网站好莱| 青青草观看免费视频在线| 欧美亚洲国产一区在线观看网站| 在线免费看毛片| 成人免费网站黄| 国产精品国产三级国产普通话蜜臀| 漂亮人妻被中出中文字幕| 日日夜夜操操操| 亚洲一区二区三区成人|