精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

国产精品一二三在| 91精品综合| 欧美视频一区二区三区| 一区二区免费在线视频| 亚洲精品一区二区三区新线路 | 九一国产在线观看| 成人直播大秀| 亚洲激情视频网站| 在线不卡一区二区三区| 中文字幕高清在线播放| 亚洲精品中文在线观看| 日韩精品资源| 欧美视频在线观看一区二区三区| 免费高清在线视频一区·| 欧美精品成人在线| 蜜桃av免费在线观看| 麻豆精品av| 欧美一二三在线| 国内自拍视频网| av影片在线| 国产精品第四页| 欧美自拍资源在线| 六月丁香综合网| 国产一区二区三区在线看麻豆| 日本最新高清不卡中文字幕| 国产精品suv一区二区69| 99久久99视频只有精品| 亚洲欧洲高清在线| 久久人妻一区二区| 亚洲精品福利| 91麻豆精品91久久久久同性| 婷婷丁香激情网| 欧美三级网址| 日韩欧美aⅴ综合网站发布| 97碰在线视频| 日本乱理伦在线| 亚洲人成网站精品片在线观看| 少妇精品久久久久久久久久| 视频三区在线观看| 91亚洲午夜精品久久久久久| 国产一区二区久久久| 成人h动漫精品一区二区无码 | 国产精品美女主播在线观看纯欲| 国产69精品久久久久久久久久| 亚洲五月婷婷| 高清亚洲成在人网站天堂| 久操视频免费在线观看| 午夜欧美精品久久久久久久| 欧美大片免费观看| 精品人妻在线播放| 欧美视频官网| 久久久噜久噜久久综合| 国产乡下妇女做爰视频| 亚洲激情专区| 77777少妇光屁股久久一区| 国产网址在线观看| 亚洲精品偷拍| 69av在线视频| 精品国产乱子伦| 日韩高清在线不卡| 国产精品久久久久久久av大片| 久久影视中文字幕| 免费在线观看视频一区| 欧美日韩爱爱| 日韩免费高清视频| 国产精品无码自拍| 久久久伦理片| 亚洲视频在线观看免费| 欧美一区二区三区粗大| 欧美xxxxx视频| 欧美大肥婆大肥bbbbb| 久久久久97国产| 夜夜嗨一区二区三区| 日韩av手机在线| 在线观看中文字幕av| 激情五月婷婷综合| 国产精品美女诱惑| 欧美日韩视频精品二区| 欧美激情一区二区三区四区| 中文字幕日韩一区二区三区不卡| 97caopor国产在线视频| 午夜国产精品一区| 韩国视频一区二区三区| 国产高清日韩| 国产网站欧美日韩免费精品在线观看| 成人性生交大片免费看无遮挡aⅴ| 国产精品国产三级国产在线观看 | 久久国产视频网| 99国产视频在线| 美州a亚洲一视本频v色道| 日韩一区欧美小说| 亚洲人精品午夜射精日韩| 欧美美女日韩| 日韩亚洲欧美成人一区| 超碰97人人干| 午夜精品久久| 国产精品久久久久久影视 | 看片一区二区| 亚洲第一精品夜夜躁人人爽| 免费看日本黄色片| 激情五月***国产精品| 国产精品亚洲网站| 日本加勒比一区| 中文字幕一区二区视频| 乱妇乱女熟妇熟女网站| 精品国产伦一区二区三区观看说明 | www.国产福利| 伊人久久综合影院| 欧美精品videosex极品1| 亚洲一区二区激情| 26uuu精品一区二区| 国产盗摄视频在线观看| **在线精品| 亚洲国产高潮在线观看| 免费看特级毛片| 日韩综合一区二区| 九九九九精品九九九九| 免费看电影在线| 在线播放中文字幕一区| 中文精品在线观看| 在线 亚洲欧美在线综合一区| 国产日韩欧美夫妻视频在线观看| 丝袜视频国产在线播放| 一区二区三区加勒比av| 中文字幕第100页| 欧美猛男同性videos| 午夜精品久久久久久久男人的天堂| 国产又粗又猛又爽又黄的视频一| 久久久久国产精品人| 日本福利视频在线| 538任你躁精品视频网免费| 精品国产区一区二区三区在线观看| 亚洲欧美精品一区二区三区| jlzzjlzz国产精品久久| 欧美日韩不卡在线视频| 成人精品动漫一区二区三区| 欧美大片第1页| 亚洲福利在线观看视频| 亚洲另类在线制服丝袜| 91丨porny丨九色| 亚洲精品午夜av福利久久蜜桃| 国产精品在线看| 成人高清在线| 欧美日韩亚洲国产综合| 老司机精品免费视频| 强制捆绑调教一区二区| 亚洲在线欧美| 国产亚洲久久| 欧美精品在线第一页| 精品女同一区二区三区| 一区二区三区四区在线免费观看| 久久人人爽人人片| 女人香蕉久久**毛片精品| 91视频免费进入| 美女航空一级毛片在线播放| 亚洲第一精品自拍| 天天爽夜夜爽夜夜爽精品| 久久在线免费观看| 国产一级不卡毛片| 色天天综合网| av资源站久久亚洲| 国产蜜臀av在线播放| 亚洲国产精品小视频| 国产三级精品三级在线观看| 国产日韩欧美不卡在线| 激情黄色小视频| 欧美日韩在线大尺度| 久久久久高清| 精品69视频一区二区三区| 另类天堂视频在线观看| 日韩在线视频免费| 91福利在线观看| 污软件在线观看| 波多野结衣在线aⅴ中文字幕不卡| 69堂免费视频| 久久性感美女视频| 高清一区二区三区视频| 第84页国产精品| 色噜噜狠狠狠综合曰曰曰| 精品国产乱码久久久久久蜜臀网站| 精品久久久久久亚洲国产300 | 亚洲av成人精品一区二区三区在线播放| 欧美视频在线观看 亚洲欧| 国产精品1区2区3区4区| 国产精品1024| 色一情一乱一伦一区二区三区日本| 91青青国产在线观看精品| 国产伦精品一区二区| 国产一区二区三区四区五区3d| 九九久久精品一区| 日本一区高清| 日韩一区二区视频| 亚洲色成人www永久网站| 尤物视频一区二区| 一级性生活大片| 国产精品一区二区黑丝| 黄色一级二级三级| 激情久久五月| eeuss中文| 综合干狼人综合首页| 亚洲www视频| 欧美123区| 97视频在线观看网址| 在线视频91p| 国产视频精品一区二区三区| 精品人妻一区二区三区麻豆91| 在线观看日韩一区| 日本特黄特色aaa大片免费| 国产精品久久久久久久久久免费看| 人妖粗暴刺激videos呻吟| 久草精品在线观看| 人妻内射一区二区在线视频| 国产精品sm| 少妇熟女一区二区| 欧美一二区在线观看| 久久国产欧美精品| 88久久精品| 亚洲va久久久噜噜噜| 午夜av成人| 日本免费在线精品| 黄在线观看免费网站ktv| 色综合男人天堂| 老司机av在线免费看| 永久免费看mv网站入口亚洲| 日韩有码电影| 日韩精品免费视频| 亚洲欧美国产高清va在线播放| 色综合久久天天综合网| 色www亚洲国产阿娇yao| 久久久久久久久久久99999| 精品熟女一区二区三区| 国产乱理伦片在线观看夜一区| 天天干天天干天天干天天干天天干| 在线亚洲欧美| 日韩欧美国产综合在线| 午夜视频一区| 好吊色一区二区三区| 国产精品美女久久久久久2018 | 99视频有精品| 久久国产免费视频| 国产一区二区日韩精品| 手机免费看av网站| 理论电影国产精品| 中文字幕第100页| 久久99国产乱子伦精品免费| 亚洲精品综合在线观看| 国产自产高清不卡| 亚洲五月激情网| 国产高清不卡二三区| 无码人妻丰满熟妇啪啪网站| 高清在线不卡av| xxxwww国产| 91免费小视频| 一道本在线观看| 欧美极品少妇xxxxⅹ高跟鞋 | 免费看91视频| 不卡的av在线| 国产偷人妻精品一区| 久久先锋影音av鲁色资源网| 国产又粗又猛又爽又黄av| 国产精品美女视频| 欧美手机在线观看| 亚洲综合一区二区三区| 天天综合网入口| 欧美亚洲一区二区在线| 国产精品国产av| 精品久久国产字幕高潮| 日本a一级在线免费播放| 国产亚洲欧美aaaa| 黄色在线免费| 97在线视频精品| 日韩av电影资源网| 亚洲xxxxx| 日韩精品欧美大片| 亚洲一区二区三区欧美| 欧美午夜a级限制福利片| 成人在线免费观看av| 免费成人美女在线观看| 超级砰砰砰97免费观看最新一期 | 视频一区二区精品| 91tv官网精品成人亚洲| 激情深爱综合网| 琪琪一区二区三区| 国产精品99精品无码视亚| 久久欧美一区二区| 一级片一级片一级片| 五月婷婷激情综合| 一区二区精品视频在线观看| 亚洲成色777777女色窝| 91看片在线观看| 午夜精品福利视频| 婷婷久久免费视频| 久久艳妇乳肉豪妇荡乳av| 68国产成人综合久久精品| 日本在线观看a| 国产成人亚洲综合a∨婷婷| wwwwxxxx国产| 亚洲国产精品天堂| 在线免费a视频| 日韩精品中文字幕在线观看| 制服丝袜中文字幕在线| 国产精品91视频| 国产精品zjzjzj在线观看| 亚洲午夜精品福利| 香蕉久久久久久久av网站| 无码人妻少妇色欲av一区二区| 国产亚洲精品福利| 欧美不卡视频在线观看| 欧美一级精品在线| 9191在线观看| 国产不卡在线观看| 欧美电影完整版在线观看| 欧美另类videosbestsex日本| 奇米色一区二区| 女尊高h男高潮呻吟| 亚洲一区二区视频在线观看| 国产绿帽一区二区三区| 在线视频欧美性高潮| 成人片免费看| 国产日韩一区欧美| 欧美日韩精品免费观看视频完整| www.久久久精品| 欧美激情中文字幕| 蜜臀精品一区二区三区| 亚洲国产免费av| 日本小视频在线免费观看| 亚洲影影院av| 亚洲不卡av不卡一区二区| 一区二区xxx| 国产精品视频你懂的| 波多野结衣黄色网址| 亚洲女人初尝黑人巨大| 中文不卡1区2区3区| 欧美高清视频一区| 国产精品毛片| wwwwww日本| 色婷婷av一区二区| 黄色在线网站| 国产精品久久久久久久9999| 欧美亚洲精品在线| 国产福利在线免费| 国产精品久久久久影视| 91麻豆国产在线| 久久久精品久久久| 电影91久久久| 免费的av在线| 岛国av在线一区| 国产做受高潮漫动| 亚洲欧美综合v| 激情久久99| 经典三级在线视频| 成人精品视频.| 99热只有这里有精品| 亚洲人成在线观看网站高清| 69堂精品视频在线播放| 三年中国中文在线观看免费播放| 韩国成人在线视频| 18精品爽视频在线观看| 亚洲第一av网| 在线一区视频观看| www.亚洲一区二区| 成人av电影在线观看| 五月激情六月丁香| 亚洲精品自拍第一页| 日韩欧美一区二区三区免费观看| 亚洲一卡二卡| 成人中文字幕在线| 欧美日韩一二三四区| 在线观看久久av| 深夜福利一区| 六月丁香婷婷在线| 国产精品久久久久久久久晋中| 国产成人毛毛毛片| 欧美一区二区.| 99久久视频| 在线免费播放av| 欧美日韩亚洲综合在线 | 中文在线观看免费| 久久久久资源| 麻豆成人久久精品二区三区红| 欧美被狂躁喷白浆精品| 日韩精品一区二区三区第95| 国产91欧美| 亚洲人成无码网站久久99热国产 | 亚洲一卡二卡三卡| 成人美女视频在线观看18| 夜夜躁日日躁狠狠久久av| 免费av一区二区| 国产麻豆精品久久| xxxx国产视频| 在线免费观看日韩欧美| 色图在线观看| 亚洲高清乱码| 99天天综合性| www日本高清| 国产精品久久久久久久久久三级 | 特黄视频在线观看| 国产在线播放91| 男人的天堂成人在线| 日韩一级片大全|