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

JavaScript 中如何實現大文件并發上傳?

開發 前端
本文將介紹如何利用 async-pool 這個庫提供的 asyncPool 函數來實現大文件的并發上傳。

[[402831]]

在 JavaScript 中如何實現并發控制? 這篇文章中,阿寶哥詳細分析了 async-pool 這個庫如何利用 Promise.all 和 Promise.race 函數實現異步任務的并發控制。之后,阿寶哥通過 JavaScript 中如何實現大文件并行下載? 這篇文章介紹了 async-pool 這個庫的實際應用。

本文將介紹如何利用 async-pool 這個庫提供的 asyncPool 函數來實現大文件的并發上傳。相信有些小伙伴已經了解大文件上傳的解決方案,在上傳大文件時,為了提高上傳的效率,我們一般會使用 Blob.slice 方法對大文件按照指定的大小進行切割,然后通過多線程進行分塊上傳,等所有分塊都成功上傳后,再通知服務端進行分塊合并。

看完上圖相信你對大文件上傳的方案,已經有了一定的了解。接下來,我們先來介紹 Blob 和 File 對象。

一、Blob 和 File 對象

1.1 Blob 對象

Blob(Binary Large Object)表示二進制類型的大對象。在數據庫管理系統中,將二進制數據存儲為一個單一個體的集合。Blob 通常是影像、聲音或多媒體文件。在 JavaScript 中 Blob 類型的對象表示不可變的類似文件對象的原始數據。 為了更直觀的感受 Blob 對象,我們先來使用 Blob 構造函數,創建一個 myBlob 對象,具體如下圖所示:

如你所見,myBlob 對象含有兩個屬性:size 和 type。其中 size 屬性用于表示數據的大小(以字節為單位),type 是 MIME 類型的字符串。Blob 由一個可選的字符串 type(通常是 MIME 類型)和 blobParts 組成:

Blob 表示的不一定是 JavaScript 原生格式的數據。比如 File 接口基于 Blob,繼承了 Blob 的功能并將其擴展使其支持用戶系統上的文件。

1.2 File 對象

通常情況下, File 對象是來自用戶在一個 元素上選擇文件后返回的 FileList 對象,也可以是來自由拖放操作生成的 DataTransfer 對象,或者來自 HTMLCanvasElement 上的 mozGetAsFile() API。

File 對象是特殊類型的 Blob,且可以用在任意的 Blob 類型的上下文中。比如說 FileReader、URL.createObjectURL() 及 XMLHttpRequest.send() 都能處理 Blob 和 File。在大文件上傳的場景中,我們將使用 Blob.slice 方法對大文件按照指定的大小進行切割,然后對分塊進行并行上傳。接下來,我們來看一下具體如何實現大文件上傳。

二、如何實現大文件上傳

為了讓大家能夠更好地理解后面的內容,我們先來看一下整體的流程圖:

了解完大文件上傳的流程之后,我們先來定義上述流程中涉及的一些輔助函數。

2.1 定義輔助函數

2.1.1 定義 calcFileMD5 函數

顧名思義 calcFileMD5 函數,用于計算文件的 MD5 值(數字指紋)。在該函數中,我們使用 FileReader API 分塊讀取文件的內容,然后通過 spark-md5 這個庫提供的方法來計算文件的 MD5 值。

  1. function calcFileMD5(file) { 
  2.   return new Promise((resolve, reject) => { 
  3.     let chunkSize = 2097152, // 2M 
  4.       chunks = Math.ceil(file.size / chunkSize), 
  5.       currentChunk = 0, 
  6.       spark = new SparkMD5.ArrayBuffer(), 
  7.       fileReader = new FileReader(); 
  8.  
  9.       fileReader.onload = (e) => { 
  10.         spark.append(e.target.result); 
  11.         currentChunk++; 
  12.         if (currentChunk < chunks) { 
  13.           loadNext(); 
  14.         } else { 
  15.           resolve(spark.end()); 
  16.         } 
  17.       }; 
  18.  
  19.       fileReader.onerror = (e) => { 
  20.         reject(fileReader.error); 
  21.         reader.abort(); 
  22.       }; 
  23.  
  24.       function loadNext() { 
  25.         let start = currentChunk * chunkSize, 
  26.           end = start + chunkSize >= file.size ? file.size : start + chunkSize; 
  27.         fileReader.readAsArrayBuffer(file.slice(start, end)); 
  28.       } 
  29.       loadNext(); 
  30.   }); 

2.1.2 定義 asyncPool 函數

在 JavaScript 中如何實現并發控制? 這篇文章中,我們介紹了 asyncPool 函數,它用于實現異步任務的并發控制。該函數接收 3 個參數:

  • poolLimit(數字類型):表示限制的并發數;
  • array(數組類型):表示任務數組;
  • iteratorFn(函數類型):表示迭代函數,用于實現對每個任務項進行處理,該函數會返回一個 Promise 對象或異步函數。
  1. async function asyncPool(poolLimit, array, iteratorFn) { 
  2.   const ret = []; // 存儲所有的異步任務 
  3.   const executing = []; // 存儲正在執行的異步任務 
  4.   for (const item of array) { 
  5.     // 調用iteratorFn函數創建異步任務 
  6.     const p = Promise.resolve().then(() => iteratorFn(item, array)); 
  7.     ret.push(p); // 保存新的異步任務 
  8.  
  9.     // 當poolLimit值小于或等于總任務個數時,進行并發控制 
  10.     if (poolLimit <= array.length) { 
  11.       // 當任務完成后,從正在執行的任務數組中移除已完成的任務 
  12.       const e = p.then(() => executing.splice(executing.indexOf(e), 1)); 
  13.       executing.push(e); // 保存正在執行的異步任務 
  14.       if (executing.length >= poolLimit) { 
  15.         await Promise.race(executing); // 等待較快的任務執行完成 
  16.       } 
  17.     } 
  18.   } 
  19.   return Promise.all(ret); 

2.1.3 定義 checkFileExist 函數

checkFileExist 函數用于檢測文件是否已經上傳過了,如果已存在則秒傳,否則返回已上傳的分塊 ID 列表:

  1. function checkFileExist(url, name, md5) { 
  2.   return request.get(url, { 
  3.     params: { 
  4.       name
  5.       md5, 
  6.     }, 
  7.   }).then((response) => response.data); 

在 checkFileExist 函數中使用到的 request 對象是 Axios 實例,通過 axios.create方法來創建:

  1. const request = axios.create({ 
  2.   baseURL: "http://localhost:3000/upload"
  3.   timeout: 10000, 
  4. }); 

有了 request 對象之后,我們就可以輕易地發送 HTTP 請求。在 checkFileExist 函數內部,我們會發起一個 GET 請求,同時攜帶的查詢參數是文件名(name)和文件的 MD5 值。

2.1.4 定義 upload 函數

當調用 checkFileExist 函數之后,如果發現文件尚未上傳或者只上傳完部分分塊的話,就會繼續調用 upload 函數來執行上傳任務。在 upload 函數內,我們使用了前面介紹的 asyncPool 函數來實現異步任務的并發控制,具體如下所示:

  1. function upload({  
  2.   url, file, fileMd5,  
  3.   fileSize, chunkSize, chunkIds, 
  4.   poolLimit = 1, 
  5. }) { 
  6.   const chunks = typeof chunkSize === "number" ? Math.ceil(fileSize / chunkSize) : 1; 
  7.   return asyncPool(poolLimit, [...new Array(chunks).keys()], (i) => { 
  8.     if (chunkIds.indexOf(i + "") !== -1) { // 已上傳的分塊直接跳過 
  9.       return Promise.resolve(); 
  10.     } 
  11.     let start = i * chunkSize; 
  12.     let end = i + 1 == chunks ? fileSize : (i + 1) * chunkSize; 
  13.     const chunk = file.slice(start, end); // 對文件進行切割 
  14.     return uploadChunk({ 
  15.       url, 
  16.       chunk, 
  17.       chunkIndex: i, 
  18.       fileMd5, 
  19.       fileName: file.name
  20.     }); 
  21.   }); 

對于切割完的文件塊,會通過 uploadChunk 函數,來執行實際的上傳操作:

  1. function uploadChunk({ url, chunk, chunkIndex, fileMd5, fileName }) { 
  2.   let formData = new FormData(); 
  3.   formData.set("file", chunk, fileMd5 + "-" + chunkIndex); 
  4.   formData.set("name", fileName); 
  5.   formData.set("timestamp"Date.now()); 
  6.   return request.post(url, formData); 

2.1.5 定義 concatFiles 函數

當所有分塊都上傳完成之后,我們需要通知服務端執行分塊合并操作,這里我們定義了 concatFiles 函數來實現該功能:

  1. function concatFiles(url, name, md5) { 
  2.   return request.get(url, { 
  3.     params: { 
  4.       name
  5.       md5, 
  6.     }, 
  7.   }); 

2.1.6 定義 uploadFile 函數

在前面已定義輔助函數的基礎上,我們就可以根據大文件上傳的整體流程圖來實現一個 uploadFile 函數:

  1. async function uploadFile() { 
  2.   if (!uploadFileEle.files.length) return
  3.   const file = uploadFileEle.files[0]; // 獲取待上傳的文件 
  4.   const fileMd5 = await calcFileMD5(file); // 計算文件的MD5 
  5.   const fileStatus = await checkFileExist(  // 判斷文件是否已存在 
  6.     "/exists",  
  7.     file.name, fileMd5 
  8.   ); 
  9.   if (fileStatus.data && fileStatus.data.isExists) { 
  10.     alert("文件已上傳[秒傳]"); 
  11.     return
  12.   } else { 
  13.     await upload({ 
  14.       url: "/single"
  15.       file, // 文件對象 
  16.       fileMd5, // 文件MD5值 
  17.       fileSize: file.size, // 文件大小 
  18.       chunkSize: 1 * 1024 * 1024, // 分塊大小 
  19.       chunkIds: fileStatus.data.chunkIds, // 已上傳的分塊列表 
  20.       poolLimit: 3, // 限制的并發數 
  21.      }); 
  22.   } 
  23.   await concatFiles("/concatFiles", file.name, fileMd5); 

2.2 大文件并發上傳示例

定義完 uploadFile 函數,要實現大文件并發上傳的功能就很簡單了,具體代碼如下所示:

  1. <!DOCTYPE html> 
  2. <html lang="zh-CN"
  3.   <head> 
  4.     <meta charset="UTF-8" /> 
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 
  6.     <meta http-equiv="X-UA-Compatible" content="ie=edge" /> 
  7.     <title>大文件并發上傳示例(阿寶哥)</title> 
  8.     <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script> 
  9.     <script src="https://cdn.bootcdn.net/ajax/libs/spark-md5/3.0.0/spark-md5.min.js"></script> 
  10.   </head> 
  11.   <body> 
  12.     <input type="file" id="uploadFile" /> 
  13.     <button id="submit" onclick="uploadFile()">上傳文件</button> 
  14.     <script> 
  15.       const uploadFileEle = document.querySelector("#uploadFile"); 
  16.  
  17.       const request = axios.create({ 
  18.         baseURL: "http://localhost:3000/upload"
  19.         timeout: 10000, 
  20.       }); 
  21.  
  22.       async function uploadFile() { 
  23.         if (!uploadFileEle.files.length) return
  24.      const file = uploadFileEle.files[0]; // 獲取待上傳的文件 
  25.      const fileMd5 = await calcFileMD5(file); // 計算文件的MD5 
  26.         // ... 
  27.       } 
  28.       // 省略其他函數 
  29.     </script> 
  30.   </body> 
  31. </html> 

由于完整的示例代碼內容比較多,阿寶哥就不放具體的代碼了。感興趣的小伙伴,可以訪問以下地址瀏覽客戶端和服務器端代碼。

  • 完整的示例代碼(代碼僅供參考,可根據實際情況進行調整):
  • https://gist.github.com/semlinker/b211c0b148ac9be0ac286b387757e692

最后我們來看一下大文件并發上傳示例的運行結果:

三、總結

本文介紹了在 JavaScript 中如何利用 async-pool 這個庫提供的 asyncPool 函數,來實現大文件的并發上傳。此外,文中我們也使用了 spark-md5 這個庫來計算文件的數字指紋,如果你數字指紋感興趣的話,可以閱讀 數字指紋有什么用?趕緊來了解一下 這篇文章。

由于篇幅有限,阿寶哥并未介紹服務端的具體代碼。其實在做文件分塊合并時,阿寶哥是以流的形式進行合并,感興趣的小伙伴可以自行閱讀一下相關代碼。如果有遇到不清楚的地方,歡迎隨時跟阿寶哥交流喲。

四、參考資源

  • 你不知道的 Blob
  • MDN - File
  • MDN - ArrayBuffer
  • MDN - HTTP請求范圍
  • JavaScript 中如何實現并發控制?

 

責任編輯:姜華 來源: 全棧修仙之路
相關推薦

2021-04-19 05:41:04

JavaScript大文件下載

2020-04-02 20:07:17

前端vuenote.js

2021-04-07 06:00:18

JavaScript 前端并發控制

2022-06-13 14:06:33

大文件上傳前端

2010-02-05 08:32:32

ASP.NET MVC

2009-12-07 09:45:23

PHP上傳大文件設置

2013-03-22 14:42:01

OSS開放存儲服務云計算

2024-06-17 09:02:01

2021-01-12 10:22:45

JavaScript并發控制前端

2022-08-05 08:40:37

架構

2009-11-16 11:41:19

PHP上傳大文件

2009-07-21 15:38:31

2021-01-15 11:40:44

文件Java秒傳

2025-07-03 07:41:34

2024-07-02 10:18:18

2009-07-20 16:09:39

2009-07-08 09:29:58

WebWork

2025-03-28 05:10:00

Spring上傳大文件

2009-07-21 16:05:58

ASP.NET大文件上

2024-03-27 08:28:31

元素拖拽API文件上傳
點贊
收藏

51CTO技術棧公眾號

久久电影一区二区| 日韩欧美主播在线| 国产成人精品一区二区三区福利 | 欧美成人精品一区二区| www.黄色网| 欧美电影网站| 中文字幕一区二区不卡| 99在线看视频| 国产成人a v| 女主播福利一区| 亚洲美女精品久久| 久久久久久久久久久久久久久国产| av在线影院| 久久综合九色综合97婷婷| 国产九九精品视频| 日本少妇毛茸茸高潮| 精品色999| 亚洲国产成人精品久久| 欧美婷婷精品激情| а√天堂资源官网在线资源| 国产精品视频麻豆| 国产精选在线观看91| 欧美男人天堂网| 亚洲大片在线| 久久伊人色综合| 国内精品久久99人妻无码| 日韩成人精品一区二区三区| 欧美午夜www高清视频| 丰满女人性猛交| 黄色免费在线播放| 成人av免费在线观看| 国产噜噜噜噜久久久久久久久| 九九热在线视频播放| 亚洲91中文字幕无线码三区| 亚洲色图偷窥自拍| www.男人天堂| 蜜桃在线一区| 在线播放视频一区| 91色国产在线| 最新中文字幕在线播放| 亚洲成av人片一区二区三区| 久久av喷吹av高潮av| 国产黄在线播放| 久久久久国产精品免费免费搜索| 肥熟一91porny丨九色丨| 国产伦精品一区二区三区免.费| 久久一区欧美| 欧美在线xxx| 日韩精品久久久久久久酒店| 欧美日韩三级电影在线| 久久的精品视频| 毛片久久久久久| 欧美日韩在线二区| 一区二区三区天堂av| 黄瓜视频污在线观看| 猫咪成人在线观看| 亚洲激情视频在线播放| 性色av蜜臀av浪潮av老女人 | 亚洲国产综合在线看不卡| 久久精品99久久久香蕉| 香蕉久久久久久久| 欧美独立站高清久久| 中文字幕视频在线免费欧美日韩综合在线看 | 丝袜亚洲另类欧美综合| 欧美做受高潮1| 日本天堂网在线| 亚洲欧美日本国产专区一区| 91精品国产免费久久久久久| 国产精品第72页| 亚洲激情欧美| 4388成人网| 无码人妻丰满熟妇区bbbbxxxx | 精品国产中文字幕第一页| 亚洲精品日韩欧美| 免费看黄色av| 99热精品久久| 久久99久久亚洲国产| 久视频在线观看| 999亚洲国产精| 91爱视频在线| 免费在线不卡av| 久久99精品国产麻豆婷婷洗澡| 成人免费视频在线观看超级碰| 一级特黄aaa大片| 国产精品一区二区在线看| yellow视频在线观看一区二区| 天天摸天天碰天天爽天天弄| 久久亚洲影视婷婷| 亚洲国产精品123| 好操啊在线观看免费视频| 亚洲一区二区在线视频| 免费黄色福利视频| 国产黄色精品| 精品久久一区二区三区| 蜜桃传媒一区二区亚洲av| 欧美国产偷国产精品三区| 欧美黑人性猛交| 最新中文字幕一区| 国内精品久久久久影院一蜜桃| 91免费版网站在线观看| 人成在线免费视频| 亚洲欧美一区二区视频| 国产美女永久无遮挡| 免费成人动漫| 欧美va亚洲va香蕉在线| 男人操女人动态图| 午夜精品影院| 国产精品99久久久久久久久久久久| 92久久精品一区二区| av一二三不卡影片| 伊人久久大香线蕉综合75| 精品精品导航| 欧美日韩亚洲综合一区| 91丝袜在线观看| 国产精品97| 日本精品免费一区二区三区| 国产肥老妇视频| 国产亚洲va综合人人澡精品 | 国产精品久久国产精品| h网站视频在线观看| 亚洲大片在线观看| а 天堂 在线| 国产影视一区| 4k岛国日韩精品**专区| a网站在线观看| 国产精品水嫩水嫩| 无码人妻精品一区二区三区在线| 九色精品蝌蚪| 最好看的2019年中文视频 | 欧美婷婷六月丁香综合色| 高清中文字幕mv的电影| 亚洲v在线看| 国产精品一区二区三区毛片淫片| 午夜影院免费体验区| 亚洲精品大片www| 免费看涩涩视频| 国产中文字幕一区二区三区| 98视频在线噜噜噜国产| 亚洲黄色小说网| 亚洲精品自拍动漫在线| 国产传媒免费观看| 不卡一区2区| 国产成人综合一区二区三区| 三级黄视频在线观看| 亚洲成在人线在线播放| 久久久精品人妻一区二区三区| 99精品电影| 国产精品自拍小视频| 国产高清视频免费最新在线| 欧美日韩亚洲系列| 一级黄色电影片| 国产精品jizz在线观看美国| 亚洲a级在线观看| 成人区精品一区二区不卡| 欧美视频日韩视频| 东京热无码av男人的天堂| 日韩成人免费电影| 亚州欧美一区三区三区在线| 韩国女主播一区二区| 国产一区二区三区高清在线观看 | 欧美日韩高清一区二区三区| 精品一区二区6| 美腿丝袜一区二区三区| 在线成人性视频| 国产精品99久久免费| 欧美成人在线影院| 性中国古装videossex| 亚洲超丰满肉感bbw| 中文字幕影片免费在线观看| 免费亚洲婷婷| 欧美中文娱乐网| xxxxx.日韩| 久久香蕉频线观| 亚洲女人18毛片水真多| 偷拍与自拍一区| av男人的天堂av| 老鸭窝一区二区久久精品| 中文字幕一区综合| 88久久精品| 欧美在线视频一二三| 国产中文字幕在线视频| 欧美日韩国产高清一区二区| 免费一级全黄少妇性色生活片| 99久久婷婷国产精品综合| 99精品视频播放| 欧美丰满老妇| 精品免费视频123区| 国产精品高清乱码在线观看 | 欧美极品色图| 宅男噜噜噜66国产精品免费| 欧美精品18videosex性欧美| 日韩精品视频无播放器在线看 | 99热这里只有精品首页| 26uuu国产精品视频| 在线观看黄色av| 日韩精品专区在线影院观看| 欧美激情黑白配| 中文字幕中文字幕一区| 波多野结衣一二三区| 另类小说欧美激情| 欧美精品自拍视频| 精品视频日韩| 国产欧美日本在线| 草民电影神马电影一区二区| 久久久久久中文| 国产精品秘入口| 精品国产一区二区三区不卡| 国产一区二区视频网站| 亚洲综合在线第一页| 少妇av片在线观看| 成人18精品视频| 樱花草www在线| 久久亚洲风情| 亚洲人成无码网站久久99热国产| re久久精品视频| 国产一区二区视频在线免费观看| 日本成人在线网站| 日本成人激情视频| 1769免费视频在线观看| 在线观看不卡av| 亚洲 精品 综合 精品 自拍| 91精品国产一区二区三区蜜臀| 日韩在线播放中文字幕| 亚洲一区视频在线| 国产精品视频一区二区三| 国产亚洲精品资源在线26u| 乱码一区二区三区| 韩国一区二区三区| 日日噜噜噜噜久久久精品毛片| 亚洲精品四区| 日韩国产小视频| 亚洲在线久久| 亚洲午夜精品福利| 精品国产一区二区三区久久久樱花| 韩日午夜在线资源一区二区| 欧美专区一区| 亚洲影影院av| 91麻豆精品国产综合久久久 | 欧美亚洲黄色| 国产精品第1页| 免费电影日韩网站| 2019最新中文字幕| 国产伦子伦对白在线播放观看| 美女少妇精品视频| 黄色av电影在线观看| www.亚洲成人| 免费a级毛片在线播放| 这里只有精品视频| 国产裸舞福利在线视频合集| 亚洲欧美另类自拍| 日本又骚又刺激的视频在线观看| 亚洲精品福利视频| 天天操天天操天天操| 欧美精品一区二区三区很污很色的| 国产成人精品av在线观| 91精品国产91久久综合桃花 | 偷拍自拍在线看| 777精品视频| 手机av在线| 欧美一级在线播放| 欧美黑人一区| 国产精品福利在线观看| 国产91在线精品| 国产区精品视频| 久久中文字幕一区二区| 91高跟黑色丝袜呻吟在线观看| 日韩高清一区| 国产一区二区三区四区hd| 日韩电影在线观看完整免费观看| 久久riav| 国产成人影院| 午夜啪啪免费视频| 欧美日韩伊人| 日韩中文字幕在线视频观看| 久久青草久久| 57pao国产成永久免费视频| 韩日精品视频一区| 亚洲视频在线播放免费| 久久久久久久久久美女| 天堂av网手机版| 有码一区二区三区| 亚洲久久在线观看| 欧美美女视频在线观看| 亚洲精品国产一区二| 国产视频综合在线| av播放在线观看| 欧美黑人xxx| 欧美free嫩15| 成人免费91在线看| 免费精品国产| 裸体大乳女做爰69| 亚洲一区二区免费看| 国内外成人免费在线视频| 国产a久久麻豆| 午夜精产品一区二区在线观看的| 1区2区3区国产精品| 日本网站免费观看| 欧美男女性生活在线直播观看| 精品国自产拍在线观看| 亚洲男人第一网站| 最新日本在线观看| 国产精品99久久久久久久久久久久| 日韩精品免费视频一区二区三区 | 日韩欧美理论片| 91视频观看免费| 成人免费毛片xxx| 欧美日韩一区二区在线| 国产又黄又粗又硬| 亚洲精品丝袜日韩| 色呦呦网站在线观看| 国产精品91一区| 成人三级毛片| 日韩人妻精品一区二区三区| 久久国产精品99国产| 18深夜在线观看免费视频| 久久久www免费人成精品| 久久久夜色精品| 欧美色图一区二区三区| 日本免费一区二区三区最新| 欧美久久精品一级黑人c片| 成人不卡视频| 精品久久久久久中文字幕动漫| 亚州av乱码久久精品蜜桃 | 不卡av播放| 国产高清在线一区| 2023国产精品久久久精品双 | 国产麻豆精品视频| 欧美三级视频网站| 欧美性色xo影院| 日本免费网站在线观看| 免费97视频在线精品国自产拍| 成人免费一区| 日本一区二区久久精品| 亚洲视频www| 中国免费黄色片| 亚洲最色的网站| 性中国古装videossex| 久久精品日韩欧美| 97超碰色婷婷| 国产精品国产亚洲精品| 午夜精品美女久久久久av福利 | 国产精品少妇在线视频| www.色精品| 国产稀缺真实呦乱在线| 欧美xingq一区二区| 在线观看wwwxxxx| 91欧美精品午夜性色福利在线| 色婷婷综合网| 三上悠亚在线一区二区| 欧美激情一区在线观看| 亚洲精品国产无码| 一区二区三区无码高清视频| a屁视频一区二区三区四区| 欧美自拍资源在线| 久久夜色精品| 美国一级黄色录像| 欧美久久久久久久久久| 日本最新在线视频| 91九色视频导航| 亚洲中无吗在线| 秘密基地免费观看完整版中文| 亚洲午夜一区二区| 天天综合天天综合| 欧美中文字幕精品| 精品无人区麻豆乱码久久久| 国产又猛又黄的视频| 国产精品精品国产色婷婷| 国产普通话bbwbbwbbw| 欧美另类69精品久久久久9999| 亚洲精品午夜| 精品国产免费av| 久久久国产综合精品女国产盗摄| 国产乱码在线观看| 俺去了亚洲欧美日韩| 亚洲性视频在线| 国产91对白刺激露脸在线观看| 国产视频一区在线播放| 一区二区精品视频在线观看| 超碰精品一区二区三区乱码| 北条麻妃一区二区三区在线| 能在线观看的av| 国产精品久久免费看| 亚洲免费视频网| 国产一区二区导航在线播放| 欧美日韩亚洲第一| 国产精品久久夜| 亚洲精品国产手机| 国产成人jvid在线播放| 国产大片一区| 国产精品久久久久久亚洲色| 色又黄又爽网站www久久| 国产欧美久久久久久久久| 国产免费高清一区| 免费在线一区观看| 久草视频手机在线观看| 亚洲天堂第一页| 最新国产一区二区| 香蕉视频网站入口| 亚洲成av人片| 在线日本视频|