精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

淺探 Web Worker 與 JavaScript 沙箱

開發 前端
本文接下來的內容,將介紹我在探索基于 Web Worker 實現 JavaScript 沙箱隔離方案過程中的一些資料收集、理解以及我的踩坑和思考的過程。雖然可能整篇文章內容都在「炒冷飯」,但還是希望我的探索方案的過程能對正在看這篇文章的你有所幫助。

一些「炒冷飯」的背景介紹

本文并不會從頭開始介紹 Web Worker 的基礎知識和基本 API 的使用等(只是部分有涉及),若還未了解過 Web Worker,可參考查閱 W3C 標準 Workers 文檔 中的相關介紹。

[[392030]]

自從 2014 年 HTML5 正式推薦標準發布以來,HTML5 增加了越來越多強大的特性和功能,而在這其中,工作線程(Web Worker)概念的推出讓人眼前一亮,但未曾隨之激起多大的浪花,并被在其隨后工程側的 Angular、Vue、React 等框架的「革命」浪潮所淹沒。當然,我們總會偶然看過一些文章介紹,或出于學習的目的做過一些應用場景下的練習,甚或在實際項目中的涉及大量數據計算場景中真的使用過。但相信也有很多人和我一樣茫然,找不到這種高大上的技術在實際項目場景中能有哪些能起到廣泛作用的應用。

究其原因,Web Worker 獨立于 UI 主線程運行的特性使其被大量考慮進行性能優化方面的嘗試(比如一些圖像分析、3D 計算繪制等場景),以保證在進行大量計算的同時,頁面對用戶能有及時的響應。而這些性能優化的需求在前端側一方面涉及頻率低,另一方面也能通過微任務或服務端側處理來解決,它并不能像 Web Socket 這種技術為前端頁面下的輪詢場景的優化能帶來質的改變。

直至 2019 年爆火的微前端架構的出現,基于微應用間 JavaScript 沙箱隔離的需求,Web Worker 才得以重新從邊緣化的位置躍入到我的中心視野。根據我已經了解到的 Web Worker 的相關知識,我知道了 Web Worker 是工作在一個獨立子線程下(雖然這個子線程比起 Java 等編譯型語言的子線程實現得還有點弱,如無法加鎖等),線程之間自帶隔離的特性,那基于這種「物理」性的隔離,能不能實現 JavaScript 運行時的隔離呢?

本文接下來的內容,將介紹我在探索基于 Web Worker 實現 JavaScript 沙箱隔離方案過程中的一些資料收集、理解以及我的踩坑和思考的過程。雖然可能整篇文章內容都在「炒冷飯」,但還是希望我的探索方案的過程能對正在看這篇文章的你有所幫助。

JavaScript 沙箱

在探索基于 Web Worker 的解決方案之前,我們先要對當前要解決的問題——JavaScript 沙箱有所了解。

提到沙箱,我會先想到出于興趣玩過的沙盒游戲,但我們要探索的 JavaScript 沙箱不同于沙盒游戲,沙盒游戲注重對世界基本元素的抽象、組合以及物理力系統的實現等,而 JavaScript 沙箱則更注重在使用共享數據時對操作狀態的隔離。

在現實與 JavaScript 相關的場景中,我們知道平時使用的瀏覽器就是一個沙箱,運行在瀏覽器中的 JavaScript 代碼無法直接訪問文件系統、顯示器或其他任何硬件。Chrome 瀏覽器中每個標簽頁也是一個沙箱,各個標簽頁內的數據無法直接相互影響,接口都在獨立的上下文中運行。而在同一個瀏覽器標簽頁下運行 HTML 頁面,有哪些更細節的、對沙箱現象有需求的場景呢?

當我們作為前端開發人員較長一段時間后,我們很輕易地就能想到在同一個頁面下,使用沙箱需求的諸多應用場景,譬如:

  • 執行從不受信的源獲取到的第三方 JavaScript 代碼時(比如引入插件、處理 jsonp 請求回來的數據等)。
  • 在線代碼編輯器場景(比如著名的 codesandbox)。
  • 使用服務端渲染方案。
  • 模板字符串中的表達式的計算。
  • ... ...

這里我們先回到開頭,先將前提假設在我正在面對的微前端架構設計下。在微前端架構(推薦文章 Thinking in Microfrontend 、擁抱云時代的前端開發架構——微前端 等)中,其最關鍵的一個設計便是各個子應用間的調度實現以及其運行態的維護,而運行時各子應用使用全局事件監聽、使全局 CSS 樣式生效等常見的需求在多個子應用切換時便會成為一種污染性的副作用,為了解決這些副作用,后來出現的很多微前端架構(如 乾坤)有著各種各樣的實現。譬如 CSS 隔離中常見的命名空間前綴、Shadow DOM、 乾坤 sandbox css 的運行時動態增刪等,都有著確實行之有效的具體實踐,而這里最麻煩棘手的,還是微應用間的 JavaScript 的沙箱隔離。

在微前端架構中,JavaScript 沙箱隔離需要解決如下幾個問題:

  • 掛在 window 上的全局方法/變量(如 setTimeout、滾動等全局事件監聽等)在子應用切換時的清理和還原。
  • Cookie、LocalStorage 等的讀寫安全策略限制。
  • 各子應用獨立路由的實現。
  • 多個微應用共存時相互獨立的實現。

在 乾坤 架構設計中,關于沙箱有兩個入口文件需要關注,一個是 proxySandbox.ts,另一個是 snapshotSandbox.ts,他們分別基于 Proxy 實現代理了 window 上常用的常量和方法以及不支持 Proxy 時降級通過快照實現備份還原。結合其相關開源文章分享,簡單總結下其實現思路:起初版本使用了快照沙箱的概念,模擬 ES6 的 Proxy API,通過代理劫持 window ,當子應用修改或使用 window 上的屬性或方法時,把對應的操作記錄下來,每次子應用掛載/卸載時生成快照,當再次從外部切換到當前子應用時,再從記錄的快照中恢復,而后來為了兼容多個子應用共存的情況,又基于 Proxy 實現了代理所有全局性的常量和方法接口,為每個子應用構造了獨立的運行環境。

另外一種值得借鑒的思路是阿里云開發平臺的 Browser VM,其核心入口邏輯在 Context.js 文件中。它的具體實現思路是這樣的:

  • 借鑒 with 的實現效果,在 webpack 編譯打包階段為每個子應用代碼包裹一層代碼(見其插件包 breezr-plugin-os 下相關文件),創建一個閉包,傳入自己模擬的 window、document、location、history 等全局對象(見 根目錄下 相關文件)。
  • 在模擬的 Context 中,new 一個 iframe 對象,提供一個和宿主應用空的(about:blank) 同域 URL 來作為這個 iframe 初始加載的 URL(空的 URL 不會發生資源加載,但是會產生和這個 iframe 中關聯的 history 不能被操作的問題,這時路由的變換只支持 hash 模式),然后將其下的原生瀏覽器對象通過 contentWindow 取出來(因為 iframe 對象天然隔離,這里省去了自己 Mock 實現所有 API 的成本)。
  • 取出對應的 iframe 中原生的對象之后,繼續對特定需要隔離的對象生成對應的 Proxy,然后對一些屬性獲取和屬性設置,做一些特定的實現(比如 window.document 需要返回特定的沙箱 document 而不是當前瀏覽器的document 等)。
  • 為了文檔內容能夠被加載在同一個 DOM 樹上,對于 document,大部分的 DOM 操作的屬性和方法仍舊直接使用宿主瀏覽器中的 document 的屬性和方法處理等。

總的來說,在 Browser VM 的實現中, 可以看出其實現部分還是借鑒了 乾坤 或者說其他微前端架構的思路,比如常見全局對象的代理和攔截。并且借助 Proxy 特性,針對 Cookie、LocalStorage 的讀寫同樣能做一些安全策略的實現等。但其最大的亮點還是借助 iframe 做了一些取巧的實現,當這個為每個子應用創建的 iframe 被移除時,寫在其下 window 上的變量和 setTimeout、全局事件監聽等也會一并被移除;另外基于 Proxy,DOM 事件在沙箱中做記錄,然后在宿主中生命周期中實現移除,能夠以較小的開發成本實現整個 JavaScript 沙箱隔離的機制。

除了以上社區中現在比較火的方案,最近我也在 大型 Web 應用插件化架構探索 一文中了解到了 UI 設計領域的 Figma 產品也基于其插件系統產出了一種隔離方案。起初 Figma 同樣是將插件代碼放入 iframe 中執行并通過 postMessage 與主線程通信,但由于易用性以及 postMessage 序列化帶來的性能等問題,Figma 選擇還是將插件放入主線程去執行。Figma 采用的方案是基于目前還在草案階段 Realm API,并將 JavaScript 解釋器的一種 C++ 實現 Duktape 編譯到了 WebAssembly,然后將其嵌入到 Realm 上下文中,實現了其產品下的三方插件的獨立運行。這種方案和探索的基于 Web Worker 的實現可能能夠結合得更好,持續關注中。

Web Worker 與 DOM 渲染

在了解了 JavaScript 沙箱的「前世今生」之后,我們將目光投回本文的主角——Web Worker 身上。

正如本文開頭所說,Web Worker 子線程的形式也是一種天然的沙箱隔離,理想的方式,是借鑒 Browser VM 的前段思路,在編譯階段通過 Webpack 插件為每個子應用包裹一層創建 Worker 對象的代碼,讓子應用運行在其對應的單個 Worker 實例中,比如:

 

  1. __WRAP_WORKER__(`/* 打包代碼 */ }`); 
  2. ​ 
  3. function __WRAP_WORKER__(appCode) { 
  4.  var blob = new Blob([appCode]); 
  5.  var appWorker = new Worker(window.URL.createObjectURL(blob)); 
  6. }  

但在了解過微前端下 JavaScript 沙箱的實現過程后,我們不難發現幾個在 Web Worker 下去實現微前端場景的 JavaScript 沙箱必然會遇到的幾個難題:

  • 出于線程安全設計考慮,Web Worker 不支持 DOM 操作,必須通過 postMessage 通知 UI 主線程來實現。
  • Web Worker 無法訪問 window、document 之類的瀏覽器全局對象。

其他諸如 Web Worker 無法訪問頁面全局變量和函數、無法調用 alert、confirm 等 BOM API 等問題,相對于無法訪問 window、document 全局對象已經是小問題了。不過可喜的是,Web Worker 中可以正常使用 setTimeout、setInterval 等定時器函數,也仍能發送 ajax 請求。

所以,當先要解決問題,便是在單個 Web Worker 實例中執行 DOM 操作的問題了。首先我們有一個大前提:Web Worker 中無法渲染 DOM,所以,我們需要基于實際的應用場景,將 DOM 操作進行拆分。

React Worker DOM

因為我們微前端架構中的子應用局限在 React 技術棧下,我先將目光放在了基于 React 框架的解決方案上。

在 React 中,我們知道其將渲染階段分為對 DOM 樹的改變進行 Diff 和實際渲染改變頁面 DOM 兩個階段這一基本事實,那能不能將 Diff 過程置于 Web Worker 中,再將渲染階段通過 postMessage 與主線程進行通信后放在主線程進行呢?簡單一搜,頗為汗顏,已經有大佬在 5、6 年前就有嘗試了。這里我們可以參考下 react-worker-dom 的開源代碼。

react-worker-dom 中的實現思路很清晰。其在 common/channel.js 中統一封裝了子線程和主線程互相通信的接口和序列化通信數據的接口,然后我們可以看到其在 Worker 下實現 DOM 邏輯處理的總入口文件在 worker 目錄下,從該入口文件順藤摸瓜,可以看到其實現了計算 DOM 后通過 postMessage 通知主線程進行渲染的入口文件 WorkerBridge.js 以及其他基于 React 庫實現的 DOM 構造、Diff 操作、生命周期 Mock 接口等相關代碼,而接受渲染事件通信的入口文件在 page 目錄下,該入口文件接受 node 操作事件后再結合 WorkerDomNodeImpl.js 中的接口代碼實現了 DOM 在主線程的實際渲染更新。

簡單做下總結。基于 React 技術棧,通過在 Web Worker 下實現 Diff 與渲染階段的進行分離,可以做到一定程度的 DOM 沙箱,但這不是我們想要的微前端架構下的 JavaScript 沙箱。先不談拆分 Diff 階段與渲染階段的成本與收益比,首先,基于技術棧框架的特殊性所做的這諸多努力,會隨著這個框架本身版本的升級存在著維護升級難以掌控的問題;其次,假如各個子應用使用的技術棧框架不同,要為這些不同的框架分別封裝適配的接口,擴展性和普適性弱;最后,最為重要的一點,這種方法暫時還是沒有解決 window 下資源共享的問題,或者說,只是啟動了解決這個問題的第一步。

接下來,我們先繼續探討 Worker 下實現 DOM 操作的另外一種方案。window 下資源共享的問題我們放在其后再作討論。

AMP WorkerDOM

在我開始糾結于如 react-worker-dom 這種思路實際落地開發的諸多「天塹」問題的同時,瀏覽過其他 DOM 框架因為同樣具備插件機制偶然迸進了我的腦海,它是 Google 的 AMP。

AMP 開源項目 中除了如 amphtml 這種通用的 Web 組件框架,還有很多其他工程采用了 Shadow DOM、Web Component 等新技術,在項目下簡單刷了一眼后,我欣喜地看到了工程 worker-dom。

粗略翻看下 worker-dom 源碼,我們在 src 根目錄下可以看到 main-thread 和 worker-thread 兩個目錄,分別打開看了下后,可以發現其實現拆分 DOM 相關邏輯和 DOM 渲染的思路和上面的 react-worker-dom 基本類似,但 worker-dom 因為和上層框架無關,其下的實現更為貼近 DOM 底層。

先看 worker-thread DOM 邏輯層的相關代碼,可以看到其下的 dom 目錄 下實現了基于 DOM 標準的所有相關的節點元素、屬性接口、document 對象等代碼,上一層目錄中也實現了 Canvas、CSS、事件、Storage 等全局屬性和方法。

接著看 main-thread,其關鍵功能一方面是提供加載 worker 文件從主線程渲染頁面的接口,另一方面可以從 worker.ts 和 nodes.ts 兩個文件的代碼來理解。

在 worker.ts 中像我最初所設想的那樣包裹了一層代碼,用于自動生成 Worker 對象,并將代碼中的所有 DOM 操作都代理到模擬的 WorkerDOM 對象上:

 

  1. const code = ` 
  2.       'use strict'
  3.       (function(){ 
  4.         ${workerDOMScript} 
  5.         self['window'] = self; 
  6.         var workerDOM = WorkerThread.workerDOM; 
  7.         WorkerThread.hydrate( 
  8.           workerDOM.document, 
  9.           ${JSON.stringify(strings)}, 
  10.           ${JSON.stringify(skeleton)}, 
  11.           ${JSON.stringify(cssKeys)}, 
  12.           ${JSON.stringify(globalEventHandlerKeys)}, 
  13.           [${window.innerWidth}, ${window.innerHeight}], 
  14.           ${JSON.stringify(localStorageInit)}, 
  15.           ${JSON.stringify(sessionStorageInit)} 
  16.         ); 
  17.         workerDOM.document[${TransferrableKeys.observe}](this); 
  18.         Object.keys(workerDOM).forEach(function(k){self[k]=workerDOM[k]}); 
  19. }).call(self); 
  20. ${authorScript} 
  21. //# sourceURL=${encodeURI(config.authorURL)}`; 
  22. this[TransferrableKeys.worker] = new Worker(URL.createObjectURL(new Blob([code]))); 

在 nodes.ts 中,實現了真實元素節點的構造和存儲(基于存儲數據結構是否以及如何在渲染階段有優化還需進一步研究源碼)。

同時,在 transfer 目錄下的源碼,定義了邏輯層和 UI 渲染層的消息通信的規范。

總的來看,AMP WorkerDOM 的方案拋棄了上層框架的約束,通過從底層構造了 DOM 所有相關 API 的方式,真正做到了與框架技術棧無關。它一方面完全可以作為上層框架的底層實現,來支持各種上層框架的二次封裝遷移(如工程 amp-react-prototype),另一方面結合了當前主流 JavaScript 沙箱方案,通過模擬 window、document 全局方法的并代理到主線程的方式實現了部分的 JavaScript 沙箱隔離(暫時沒看到路由隔離的相關代碼實現)。

當然,從我個人角度來看,AMP WorkerDOM 也有其當前在落地上一定的局限性。一個是對當前主流上層框架如 Vue、React 等的遷移成本及社區生態的適配成本,另一個是其在單頁應用下的尚未看到有相關實現方案,在大型 PC 微前端應用的支持上還無法找到更優方案。

其實,在了解完 AMP WorkerDOM 的實現方案之后,基于 react-worker-dom 思路的后續方案也可以有個大概方向了:渲染通信的后續過程,可考慮結合 Browser VM 的相關實現,在生成 Worker 對象的同時,也生成一個 iframe 對象,然后將 DOM 下的操作都通過 postMessage 發送到主線程后,以與其綁定的 iframe 兌現來執行,同時,通過代理將具體的渲染實現再轉發給原 WorkerDomNodeImpl.js 邏輯來實現 DOM 的實際更新。

小結與一些個人前瞻

首先聊一聊個人的一些總結。Web Worker 下實現微前端架構下的 JavaScript 沙箱最初是出于一點個人靈光的閃現,在深入調研后,雖然最終還是因為這樣那樣的問題導致在方案落地上無法找到最優解從而放棄采用社區通用方案,但仍不妨礙我個人對 Web Worker 技術在實現插件類沙箱應用上的持續看好。插件機制在前端領域一直是津津樂道的一種設計,從 Webpack 編譯工具到 IDE 開發工具,從 Web 應用級的實體插件到應用架構設計中插件擴展設計,結合 WebAssembly 技術,Web Worker 無疑將在插件設計上占據舉足輕重的地位。

其次是一些個人的一些前瞻思考。其實從 Web Worker 實現 DOM 渲染的調研過程中可以看到,基于邏輯與 UI 分離的思路,前端后續的架構設計有很大機會能夠產生一定的變革。目前不管是盛行的 Vue 還是 React 框架,其框架設計不論是 MVVM 還是結合 Redux 之后的 Flux,其本質上仍舊還是由 View 層驅動的框架設計(個人淺見),其具備靈活性的同時也產生著性能優化、大規模項目層級升上后的協作開發困難等問題,而基于 Web Worker 的邏輯與 UI 分離,將促使數據獲取、處理、消費整個流程的進一步的業務分層,從而固化出一整套的 MVX 設計思路。

當然,以上這些我個人還處于初步調研的階段,不成熟之處還需多加琢磨。且聽之,后續再實踐之。

責任編輯:未麗燕 來源: Segmentfault.com
相關推薦

2021-01-15 07:41:24

CAS樂觀鎖Compare And

2009-11-05 12:04:48

2021-10-25 10:30:12

JavaScript開發 代碼

2013-08-20 16:44:33

2016-09-06 21:37:41

2022-05-26 09:20:01

JavaScript原型原型鏈

2020-10-12 08:35:22

JavaScript

2023-07-31 11:16:45

Web前端worker服務

2020-06-23 08:41:47

JavaScript開發技術

2012-08-31 14:23:06

2021-08-28 10:06:29

VueJavascript應用

2025-05-09 01:30:00

JavaScript事件循環基石

2014-11-05 10:31:28

2022-09-26 09:01:15

語言數據JavaScript

2024-04-01 04:00:00

JavaScript前端開發

2023-12-04 13:22:00

JavaScript異步編程

2010-07-16 09:11:40

JavaScript內存泄漏

2022-10-31 09:00:24

Promise數組參數

2012-02-21 13:55:45

JavaScript

2020-03-09 17:18:47

JavaScript技術函數
點贊
收藏

51CTO技術棧公眾號

午夜影院免费在线| 久色视频在线播放| www.久久久久久久| 久久99国产精品视频| 色综合久久久久久久久| 农村寡妇一区二区三区| 精品黑人一区二区三区| 欧美精品一二| 欧美高清视频一二三区| 乱熟女高潮一区二区在线| 亚洲精品一区二区三区新线路| 欧美r级电影| 91精品国产欧美一区二区成人| 欧美国产视频一区| 免费在线超碰| 久久国产精品色婷婷| 欧美成年人视频网站欧美| 亚洲香蕉中文网| 小早川怜子影音先锋在线观看| 中文成人综合网| 亚洲资源在线看| 久久午夜免费视频| 色小子综合网| 精品黑人一区二区三区久久| 激情六月丁香婷婷| 国产高清视频在线观看| 91精品一区二区三区综合| 五月综合激情网| 欧美日韩日本网| 国产精品视频无码| 国产毛片一区| x99av成人免费| www.日本在线播放| 精品久久av| 成人免费的视频| 国产精品久久久久久久9999| 欧美又粗又大又长| 国产亚洲第一伦理第一区| 欧美日韩午夜影院| 亚洲中文字幕无码专区| 国内精品久久久久国产| 久久久久免费观看| 成人动漫在线视频| 亚洲系列第一页| 亚洲黄色视屏| 久久久999精品视频| 五级黄高潮片90分钟视频| 国产盗摄一区二区| 国产精品无遮挡| 91福利入口| 久久久久久不卡| 亚洲手机视频| 欧美精品一区男女天堂| 国产传媒久久久| 国产在线观看精品一区| 成人h动漫精品一区二区| 国产日本欧美一区二区三区| 中文字幕国产在线观看| 欧美色一级片| 主播福利视频一区| 中文字幕av观看| 日韩一区二区三区高清在线观看| 欧美亚洲高清一区| 热re99久久精品国产99热| 精品久久久久久亚洲综合网站| 中文字幕一区二区三三| 在线观看国产欧美| 久久久久久久久久久久久久久| 99热这里只有精品首页 | 美女福利视频网| 午夜精品影视国产一区在线麻豆| 丁香五六月婷婷久久激情| 特级西西人体www高清大胆| av中文资源在线| 国产亚洲欧美日韩在线一区| 久久精品99久久| 人妻丰满熟妇av无码区hd| 91欧美在线| 亚洲天堂网在线观看| www.色天使| 国产日产一区| 国产一区二区精品丝袜| 久久中文字幕精品| 日韩av二区| 日韩在线观看你懂的| 天天舔天天操天天干| 日本一区二区高清不卡| 三级精品视频久久久久| 亚洲av成人无码久久精品| 成人午夜网址| 亚洲国产精品高清久久久| 麻豆短视频在线观看| 成人另类视频| 亚洲免费视频网站| 免费看91的网站| 日韩理论电影| 欧美日本啪啪无遮挡网站| 国产性70yerg老太| 亚洲毛片免费看| 亚洲欧洲一区二区三区久久| 舐め犯し波多野结衣在线观看| 四虎国产精品免费观看| 欧美成人自拍视频| 男人的天堂一区| 欧美日韩有码| 日韩中文字幕免费视频| 人人干在线观看| 午夜欧美理论片| 亚洲18私人小影院| 无码人妻丰满熟妇区五十路| 日韩电影在线观看电影| 91久久久久久国产精品| 亚洲女同志亚洲女同女播放| 国产高清无密码一区二区三区| 成人午夜电影免费在线观看| 日韩二区三区| 最新中文字幕一区二区三区| 久在线观看视频| 国产亚洲精彩久久| 精品国产污网站| 一区二区三区久久久久| 中文字幕一区二区三区乱码图片| 欧美亚洲成人精品| 在线观看国产小视频| 成人午夜视频在线| 亚洲欧美影院| 国产v日韩v欧美v| 欧美日韩视频在线观看一区二区三区| zjzjzjzjzj亚洲女人| 久久蜜桃av| 91大神福利视频在线| 国产精品视频a| 久久久久久久久蜜桃| 国产一区福利在线| 欧美日韩福利视频| 无码人妻熟妇av又粗又大| 国产精品一级在线| 日韩欧美亚洲精品| 97人澡人人添人人爽欧美| 中文字幕一区在线观看视频| 欧美精品自拍视频| 亚洲精品粉嫩美女一区| 亚洲成人久久久| 亚洲欧美视频在线播放| 欧美在线三区| 热门国产精品亚洲第一区在线| 国产美女www爽爽爽视频| 久久一二三四| 99久re热视频这里只有精品6| 国产免费av高清在线| 午夜精品久久久久久久99水蜜桃| 在线观看av免费观看| sdde在线播放一区二区| 97超级碰在线看视频免费在线看| 亚洲永久精品一区| 岛国一区二区在线观看| 国产大尺度在线观看| 国产第一亚洲| 亚洲人成在线观看| 亚洲男人第一av| 国产另类ts人妖一区二区| 亚洲乱码国产乱码精品天美传媒| 精品视频在线一区二区| 懂色av影视一区二区三区| 亚洲欧美日韩中文字幕在线观看| 久久在线播放| 国产精品一区二区3区| 国产精品影院在线| 91成人免费电影| 国产女主播喷水高潮网红在线| 亚洲二区视频| 国产美女99p| 波多野结依一区| 精品国产sm最大网站免费看| 国产在线一卡二卡| 麻豆91在线看| 亚洲日本理论电影| 成人免费黄色| 中文国产亚洲喷潮| 最近中文在线观看| 中文字幕乱码亚洲精品一区| 91制片厂毛片| 91亚洲国产高清| 成人福利网站在线观看11| 亚洲欧美视频一区二区| 欧美老人xxxx18| 538精品在线视频| 国产精品99久久久久久久女警| 欧妇女乱妇女乱视频| 日韩激情毛片| 国产精品白嫩美女在线观看 | 日韩精品xxx| 亚洲视频狠狠| 精品国产第一页| 粉嫩一区二区| 神马久久久久久| 99热这里只有精品66| 午夜视频一区在线观看| 熟女丰满老熟女熟妇| 日本视频一区二区| 中文字幕成人一区| eeuss国产一区二区三区四区| 午夜精品久久久久久久99热浪潮| 亚洲欧美日韩成人在线| 在线视频一区二区三区| 精品国产国产综合精品| 国产传媒欧美日韩成人| 国产性xxxx18免费观看视频| av永久不卡| 国产色综合天天综合网| 黄网址在线观看| 精品国产sm最大网站免费看| 99超碰在线观看| 亚洲欧洲中文日韩久久av乱码| 黄色一级在线视频| 国产成人一区二区三区影院| 成人国产在线激情| 波多野一区二区| 日韩中文在线中文网三级| 国精品人妻无码一区二区三区喝尿 | 亚洲一区精彩视频| www.成人在线.com| 久久精品亚洲乱码伦伦中文| 欧美人成在线视频| 可以免费看污视频的网站在线| 欧美日韩在线电影| 亚洲国产综合久久| 国产精品的网站| 亚洲 欧美 日韩在线| 麻豆中文一区二区| 日韩少妇内射免费播放| 亚洲国产精品日韩专区av有中文| 蜜桃视频日韩| 欧美天堂一区二区| 欧美亚洲伦理www| av网址在线播放| 一区二区三区视频免费| 全部免费毛片在线播放一个| 欧美精品久久久久久久多人混战| 69成人免费视频| 亚洲欧美另类图片小说| 亚洲一区二区三区四区五区六区| 久久国内精品自在自线400部| 俄罗斯av网站| 欧美在线免费一级片| 中文字幕一区二区三区5566| 啄木系列成人av电影| 国产v亚洲v天堂无码| 亚洲图片小说区| 国产精品久久久久久久久| 女海盗2成人h版中文字幕| 欧美日韩福利在线观看| 欧美成人hd| 亚洲日韩第一页| 欧美在线一卡| 日韩av中文字幕在线播放| 亚洲精品一区二区三区蜜桃| 欧美一级在线免费| 国产一区二区三区四区视频| 在线视频综合导航| 午夜精品免费观看| 色素色在线综合| 特级做a爱片免费69| 亚洲成人动漫一区| 午夜成人亚洲理伦片在线观看| 亚洲国产成人自拍| 久久视频精品在线观看| 久久色.com| 粉嫩av蜜桃av蜜臀av| 91在线国内视频| 色婷婷免费视频| 91亚洲精品久久久蜜桃网站| 91视频福利网| 麻豆一区二区99久久久久| www黄色在线| 久久影院亚洲| 亚洲视频在线a| 蜜臂av日日欢夜夜爽一区| 日本人视频jizz页码69| 久久精品国产**网站演员| 色播五月综合网| 久久99精品久久久久久国产越南| www.xxx亚洲| 久久精品国产亚洲aⅴ| 午夜免费福利网站| 高清日韩电视剧大全免费| 黄色激情在线观看| 久久综合久久综合九色| 调教驯服丰满美艳麻麻在线视频 | 日本少妇xxxx软件| 99视频一区二区| 成都免费高清电影| 中文字幕中文字幕一区二区| 澳门黄色一级片| 亚洲国产综合视频在线观看| 国产免费无码一区二区视频| 亚洲大型综合色站| 秋霞精品一区二区三区| 欧美日韩国产一区| 免费观看毛片网站| 亚洲欧美另类在线观看| 日韩黄色影院| 性欧美长视频免费观看不卡| 在线天堂资源www在线污| 国产欧美一区二区三区在线看| 24小时成人在线视频| 成人自拍网站| 大片网站久久| 97中文字幕在线| 久久久久中文| 超碰91在线播放| 91在线精品一区二区三区| 亚洲a∨无码无在线观看| 一区二区三区精品视频在线| 久久久久久久久毛片| 亚洲综合视频在线观看| 日韩在线 中文字幕| 欧美一二三在线| 在线观看的av| 日韩一区二区久久久| av在线资源| 成人美女免费网站视频| 奇米777国产一区国产二区| 一区二区三区av| 国产亚洲在线观看| 欧美日韩久久婷婷| 久久综合资源网| www.com.av| 亚洲动漫第一页| 亚洲一卡二卡在线| 国产丝袜视频一区| 在线三级中文| 国产精品视频网站| 亚洲午夜久久| 99久久精品情趣| 超碰在线97免费| 不卡大黄网站免费看| 在线观看黄网址| 色哟哟国产精品| 欧美在线 | 亚洲| 不卡av电影院| 涩爱av在线播放一区二区| 色妞在线综合亚洲欧美| 中文字幕在线高清| 97人人模人人爽人人少妇| 日本一区二区免费高清| 欧美啪啪免费视频| 国产成人av网站| 欧美日韩大尺度| 99久久国产综合精品麻豆| 日韩欧美不卡视频| 日韩电影中文 亚洲精品乱码 | 国产婷婷一区二区| 国产suv精品一区二区33| 亚洲精品日韩丝袜精品| 韩国美女久久| 日本一区二区三区免费观看| 久久这里有精品15一区二区三区| 这里只有久久精品| 欧美日韩国产一区二区| 亚洲人视频在线观看| 欧洲成人在线视频| 国产探花在线精品| www.这里只有精品| 亚洲视频在线一区观看| japanese国产| 97国产一区二区精品久久呦| 希岛爱理av免费一区二区| 999精品网站| 国产精品萝li| 国产超碰人人模人人爽人人添| 色在人av网站天堂精品| 欧美一级二级三级视频| 欧美精品成人网| 国产精品你懂的在线欣赏| 99久久精品日本一区二区免费| 日韩午夜在线| 久久久精品视频国产| 亚洲电影一区二区| 欧美精品少妇| 成人激情春色网| 精品av久久久久电影| 高潮毛片无遮挡| 3751色影院一区二区三区| 激情av在线| 日本一区二区三区视频在线观看| 乱一区二区av| 国产一级视频在线播放| 亚洲无线码在线一区观看| 亚洲欧美一级| 欧美乱大交xxxxx潮喷l头像| 欧美激情一区在线| 精品人妻少妇嫩草av无码专区| 国产91精品青草社区| 第四色成人网| 国产精品一区二区人妻喷水| 欧美日韩在线精品一区二区三区激情| 青草av在线| 视频一区视频二区视频三区视频四区国产 | 精品176二区|