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

77.9K 的 Axios 項目有哪些值得借鑒的地方

系統
Axios 是一個基于 Promise 的 HTTP 客戶端,同時支持瀏覽器和 Node.js 環境。它是一個優秀的 HTTP 客戶端,被廣泛地應用在大量的 Web 項目中。

Axios 是一個基于 Promise 的 HTTP 客戶端,同時支持瀏覽器和 Node.js 環境。它是一個優秀的 HTTP 客戶端,被廣泛地應用在大量的 Web 項目中。

由上圖可知,Axios 項目的 Star 數為 「77.9K」,Fork 數也高達 「7.3K」,是一個很優秀的開源項目,所以接下來阿寶哥將帶大家一起來分析 Axios 項目中一些值得借鑒的地方。

閱讀完本文,你將了解以下內容:

  • HTTP 攔截器的設計與實現;
  • HTTP 適配器的設計與實現;
  • 如何防御 CSRF 攻擊。

下面我們從簡單的開始,先來了解一下 Axios。

一、Axios 簡介
Axios 是一個基于 Promise 的 HTTP 客戶端,擁有以下特性:

  • 支持 Promise API;
  • 能夠攔截請求和響應;
  • 能夠轉換請求和響應數據;
  • 客戶端支持防御 CSRF 攻擊;
  • 同時支持瀏覽器和 Node.js 環境;
  • 能夠取消請求及自動轉換 JSON 數據。

在瀏覽器端 Axios 支持大多數主流的瀏覽器,比如 Chrome、Firefox、Safari 和 IE 11。此外,Axios 還擁有自己的生態:

(數據來源 —— https://github.com/axios/axios/blob/master/ECOSYSTEM.md)

簡單介紹完 Axios,我們來分析一下它提供的一個核心功能 —— 攔截器。

二、HTTP 攔截器的設計與實現
2.1 攔截器簡介
對于大多數 SPA 應用程序來說, 通常會使用 token 進行用戶的身份認證。這就要求在認證通過后,我們需要在每個請求上都攜帶認證信息。針對這個需求,為了避免為每個請求單獨處理,我們可以通過封裝統一的 request 函數來為每個請求統一添加 token 信息。

但后期如果需要為某些 GET 請求設置緩存時間或者控制某些請求的調用頻率的話,我們就需要不斷修改 request 函數來擴展對應的功能。此時,如果在考慮對響應進行統一處理的話,我們的 request 函數將變得越來越龐大,也越來越難維護。那么對于這個問題,該如何解決呢?Axios 為我們提供了解決方案 —— 攔截器。

Axios 是一個基于 Promise 的 HTTP 客戶端,而 HTTP 協議是基于請求和響應:

所以 Axios 提供了請求攔截器和響應攔截器來分別處理請求和響應,它們的作用如下:

  • 請求攔截器:該類攔截器的作用是在請求發送前統一執行某些操作,比如在請求頭中添加 token 字段。
  • 響應攔截器:該類攔截器的作用是在接收到服務器響應后統一執行某些操作,比如發現響應狀態碼為 401 時,自動跳轉到登錄頁。

在 Axios 中設置攔截器很簡單,通過 axios.interceptors.request 和 axios.interceptors.response 對象提供的 use 方法,就可以分別設置請求攔截器和響應攔截器:

  1. // 添加請求攔截器 
  2. axios.interceptors.request.use(function (config) { 
  3.   config.headers.token = 'added by interceptor'
  4.   return config; 
  5. }); 
  6.  
  7. // 添加響應攔截器 
  8. axios.interceptors.response.use(function (data) { 
  9.   data.data = data.data + ' - modified by interceptor'
  10.   return data; 
  11. }); 

那么攔截器是如何工作的呢?在看具體的代碼之前,我們先來分析一下它的設計思路。Axios 的作用是用于發送 HTTP 請求,而請求攔截器和響應攔截器的本質都是一個實現特定功能的函數。

我們可以按照功能把發送 HTTP 請求拆解成不同類型的子任務,比如有用于處理請求配置對象的子任務,用于發送 HTTP 請求的子任務和用于處理響應對象的子任務。當我們按照指定的順序來執行這些子任務時,就可以完成一次完整的 HTTP 請求。

了解完這些,接下來我們將從 「任務注冊、任務編排和任務調度」 三個方面來分析 Axios 攔截器的實現。

2.2 任務注冊
通過前面攔截器的使用示例,我們已經知道如何注冊請求攔截器和響應攔截器,其中請求攔截器用于處理請求配置對象的子任務,而響應攔截器用于處理響應對象的子任務。要搞清楚任務是如何注冊的,就需要了解 axios 和 axios.interceptors 對象。

  1. // lib/axios.js 
  2. function createInstance(defaultConfig) { 
  3.   var context = new Axios(defaultConfig); 
  4.   var instance = bind(Axios.prototype.request, context); 
  5.  
  6.   // Copy axios.prototype to instance 
  7.   utils.extend(instance, Axios.prototype, context); 
  8.   // Copy context to instance 
  9.   utils.extend(instance, context); 
  10.   return instance; 
  11.  
  12. // Create the default instance to be exported 
  13. var axios = createInstance(defaults); 

在 Axios 的源碼中,我們找到了 axios 對象的定義,很明顯默認的 axios 實例是通過 createInstance 方法創建的,該方法最終返回的是 Axios.prototype.request 函數對象。同時,我們發現了 Axios 的構造函數:

  1. // lib/core/Axios.js 
  2. function Axios(instanceConfig) { 
  3.   this.defaults = instanceConfig; 
  4.   this.interceptors = { 
  5.     request: new InterceptorManager(), 
  6.     response: new InterceptorManager() 
  7.   }; 

在構造函數中,我們找到了 axios.interceptors 對象的定義,也知道了 interceptors.request 和 interceptors.response 對象都是 InterceptorManager 類的實例。因此接下來,進一步分析 InterceptorManager 構造函數及相關的 use 方法就可以知道任務是如何注冊的:

  1. // lib/core/InterceptorManager.js 
  2. function InterceptorManager() { 
  3.   this.handlers = []; 
  4.  
  5. InterceptorManager.prototype.use = function use(fulfilled, rejected) { 
  6.   this.handlers.push({ 
  7.     fulfilled: fulfilled, 
  8.     rejected: rejected 
  9.   }); 
  10.   // 返回當前的索引,用于移除已注冊的攔截器 
  11.   return this.handlers.length - 1; 
  12. }; 

通過觀察 use 方法,我們可知注冊的攔截器都會被保存到 InterceptorManager 對象的 handlers 屬性中。下面我們用一張圖來總結一下 Axios 對象與 InterceptorManager 對象的內部結構與關系:

2.3 任務編排
現在我們已經知道如何注冊攔截器任務,但僅僅注冊任務是不夠,我們還需要對已注冊的任務進行編排,這樣才能確保任務的執行順序。這里我們把完成一次完整的 HTTP 請求分為處理請求配置對象、發起 HTTP 請求和處理響應對象 3 個階段。

接下來我們來看一下 Axios 如何發請求的:

  1. axios({ 
  2.   url: '/hello'
  3.   method: 'get'
  4. }).then(res =>{ 
  5.   console.log('axios res: ', res) 
  6.   console.log('axios res.data: ', res.data) 
  7. }) 

通過前面的分析,我們已經知道 axios 對象對應的是 Axios.prototype.request 函數對象,該函數的具體實現如下:

  1. // lib/core/Axios.js 
  2. Axios.prototype.request = function request(config) { 
  3.   config = mergeConfig(this.defaults, config); 
  4.  
  5.   // 省略部分代碼 
  6.   var chain = [dispatchRequest, undefined]; 
  7.   var promise = Promise.resolve(config); 
  8.  
  9.   // 任務編排 
  10.   this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { 
  11.     chain.unshift(interceptor.fulfilled, interceptor.rejected); 
  12.   }); 
  13.  
  14.   this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { 
  15.     chain.push(interceptor.fulfilled, interceptor.rejected); 
  16.   }); 
  17.  
  18.   // 任務調度 
  19.   while (chain.length) { 
  20.     promise = promise.then(chain.shift(), chain.shift()); 
  21.   } 
  22.  
  23.   return promise; 
  24. }; 

任務編排的代碼比較簡單,我們來看一下任務編排前和任務編排后的對比圖:

2.4 任務調度
任務編排完成后,要發起 HTTP 請求,我們還需要按編排后的順序執行任務調度。在 Axios 中具體的調度方式很簡單,具體如下所示:

  1. // lib/core/Axios.js 
  2. xios.prototype.request = function request(config) { 
  3.  // 省略部分代碼 
  4.  var promise = Promise.resolve(config); 
  5.  while (chain.length) { 
  6.    promise = promise.then(chain.shift(), chain.shift()); 
  7.  } 

因為 chain 是數組,所以通過 while 語句我們就可以不斷地取出設置的任務,然后組裝成 Promise 調用鏈從而實現任務調度,對應的處理流程如下圖所示:

下面我們來回顧一下 Axios 攔截器完整的使用流程:

  1. // 添加請求攔截器 —— 處理請求配置對象 
  2. axios.interceptors.request.use(function (config) { 
  3.   config.headers.token = 'added by interceptor'
  4.   return config; 
  5. }); 
  6.  
  7. // 添加響應攔截器 —— 處理響應對象 
  8. axios.interceptors.response.use(function (data) { 
  9.   data.data = data.data + ' - modified by interceptor'
  10.   return data; 
  11. }); 
  12.  
  13. axios({ 
  14.   url: '/hello'
  15.   method: 'get'
  16. }).then(res =>{ 
  17.   console.log('axios res.data: ', res.data) 
  18. }) 

介紹完 Axios 的攔截器,我們來總結一下它的優點。Axios 通過提供攔截器機制,讓開發者可以很容易在請求的生命周期中自定義不同的處理邏輯。

此外,也可以通過攔截器機制來靈活地擴展 Axios 的功能,比如 Axios 生態中列舉的 axios-response-logger 和 axios-debug-log 這兩個庫。

參考 Axios 攔截器的設計模型,我們就可以抽出以下通用的任務處理模型:

三、HTTP 適配器的設計與實現
3.1 默認 HTTP 適配器
Axios 同時支持瀏覽器和 Node.js 環境,對于瀏覽器環境來說,我們可以通過 XMLHttpRequest 或 fetch API 來發送 HTTP 請求,而對于 Node.js 環境來說,我們可以通過 Node.js 內置的 http 或 https 模塊來發送 HTTP 請求。

為了支持不同的環境,Axios 引入了適配器。在 HTTP 攔截器設計部分,我們看到了一個 dispatchRequest 方法,該方法用于發送 HTTP 請求,它的具體實現如下所示:

  1. // lib/core/dispatchRequest.js 
  2. module.exports = function dispatchRequest(config) { 
  3.   // 省略部分代碼 
  4.   var adapter = config.adapter || defaults.adapter; 
  5.    
  6.   return adapter(config).then(function onAdapterResolution(response) { 
  7.     // 省略部分代碼 
  8.     return response; 
  9.   }, function onAdapterRejection(reason) { 
  10.     // 省略部分代碼 
  11.     return Promise.reject(reason); 
  12.   }); 
  13. }; 

通過查看以上的 dispatchRequest 方法,我們可知 Axios 支持自定義適配器,同時也提供了默認的適配器。對于大多數場景,我們并不需要自定義適配器,而是直接使用默認的適配器。因此,默認的適配器就會包含瀏覽器和 Node.js 環境的適配代碼,其具體的適配邏輯如下所示:

  1. // lib/defaults.js 
  2. var defaults = { 
  3.   adapter: getDefaultAdapter(), 
  4.   xsrfCookieName: 'XSRF-TOKEN'
  5.   xsrfHeaderName: 'X-XSRF-TOKEN'
  6.   //... 
  7.  
  8. function getDefaultAdapter() { 
  9.   var adapter; 
  10.   if (typeof XMLHttpRequest !== 'undefined') { 
  11.     // For browsers use XHR adapter 
  12.     adapter = require('./adapters/xhr'); 
  13.   } else if (typeof process !== 'undefined' &&  
  14.     Object.prototype.toString.call(process) === '[object process]') { 
  15.     // For node use HTTP adapter 
  16.     adapter = require('./adapters/http'); 
  17.   } 
  18.   return adapter; 

在 getDefaultAdapter 方法中,首先通過平臺中特定的對象來區分不同的平臺,然后再導入不同的適配器,具體的代碼比較簡單,這里就不展開介紹。

3.2 自定義適配器
其實除了默認的適配器外,我們還可以自定義適配器。那么如何自定義適配器呢?這里我們可以參考 Axios 提供的示例:

  1. var settle = require('./../core/settle'); 
  2. module.exports = function myAdapter(config) { 
  3.   // 當前時機點: 
  4.   //  - config配置對象已經與默認的請求配置合并 
  5.   //  - 請求轉換器已經運行 
  6.   //  - 請求攔截器已經運行 
  7.    
  8.   // 使用提供的config配置對象發起請求 
  9.   // 根據響應對象處理Promise的狀態 
  10.   return new Promise(function(resolve, reject) { 
  11.     var response = { 
  12.       data: responseData, 
  13.       status: request.status, 
  14.       statusText: request.statusText, 
  15.       headers: responseHeaders, 
  16.       config: config, 
  17.       request: request 
  18.     }; 
  19.  
  20.     settle(resolve, reject, response); 
  21.  
  22.     // 此后: 
  23.     //  - 響應轉換器將會運行 
  24.     //  - 響應攔截器將會運行 
  25.   }); 

在以上示例中,我們主要關注轉換器、攔截器的運行時機點和適配器的基本要求。比如當調用自定義適配器之后,需要返回 Promise 對象。這是因為 Axios 內部是通過 Promise 鏈式調用來完成請求調度,不清楚的小伙伴可以重新閱讀 “攔截器的設計與實現” 部分的內容。

現在我們已經知道如何自定義適配器了,那么自定義適配器有什么用呢?在 Axios 生態中,阿寶哥發現了 axios-mock-adapter 這個庫,該庫通過自定義適配器,讓開發者可以輕松地模擬請求。對應的使用示例如下所示:

  1. var axios = require("axios"); 
  2. var MockAdapter = require("axios-mock-adapter"); 
  3.  
  4. // 在默認的Axios實例上設置mock適配器 
  5. var mock = new MockAdapter(axios); 
  6.  
  7. // 模擬 GET /users 請求 
  8. mock.onGet("/users").reply(200, { 
  9.   users: [{ id: 1, name"John Smith" }], 
  10. }); 
  11.  
  12. axios.get("/users").then(function (response) { 
  13.   console.log(response.data); 
  14. }); 

對 MockAdapter 感興趣的小伙伴,可以自行了解一下 axios-mock-adapter 這個庫。到這里我們已經介紹了 Axios 的攔截器與適配器,下面阿寶哥用一張圖來總結一下 Axios 使用請求攔截器和響應攔截器后,請求的處理流程:

四、CSRF 防御
4.1 CSRF 簡介
「跨站請求偽造」(Cross-site request forgery),通常縮寫為 「CSRF」 或者 「XSRF」, 是一種挾制用戶在當前已登錄的 Web 應用程序上執行非本意的操作的攻擊方法。

跨站請求攻擊,簡單地說,是攻擊者通過一些技術手段欺騙用戶的瀏覽器去訪問一個自己曾經認證過的網站并運行一些操作(如發郵件,發消息,甚至財產操作如轉賬和購買商品)。由于瀏覽器曾經認證過,所以被訪問的網站會認為是真正的用戶操作而去運行。

為了讓小伙伴更好地理解上述的內容,阿寶哥畫了一張跨站請求攻擊示例圖:

在上圖中攻擊者利用了 Web 中用戶身份驗證的一個漏洞:「簡單的身份驗證只能保證請求發自某個用戶的瀏覽器,卻不能保證請求本身是用戶自愿發出的」。既然存在以上的漏洞,那么我們應該怎么進行防御呢?接下來我們來介紹一些常見的 CSRF 防御措施。

4.2 CSRF 防御措施
4.2.1 檢查 Referer 字段
HTTP 頭中有一個 Referer 字段,這個字段用以標明請求來源于哪個地址。「在處理敏感數據請求時,通常來說,Referer 字段應和請求的地址位于同一域名下」。

以示例中商城操作為例,Referer 字段地址通常應該是商城所在的網頁地址,應該也位于 www.semlinker.com 之下。而如果是 CSRF 攻擊傳來的請求,Referer 字段會是包含惡意網址的地址,不會位于 www.semlinker.com 之下,這時候服務器就能識別出惡意的訪問。

這種辦法簡單易行,僅需要在關鍵訪問處增加一步校驗。但這種辦法也有其局限性,因其完全依賴瀏覽器發送正確的 Referer 字段。雖然 HTTP 協議對此字段的內容有明確的規定,但并無法保證來訪的瀏覽器的具體實現,亦無法保證瀏覽器沒有安全漏洞影響到此字段。并且也存在攻擊者攻擊某些瀏覽器,篡改其 Referer 字段的可能。

4.2.2 同步表單 CSRF 校驗
CSRF 攻擊之所以能夠成功,是因為服務器無法區分正常請求和攻擊請求。針對這個問題我們可以要求所有的用戶請求都攜帶一個 CSRF 攻擊者無法獲取到的 token。對于 CSRF 示例圖中的表單攻擊,我們可以使用 「同步表單 CSRF 校驗」 的防御措施。

「同步表單 CSRF 校驗」 就是在返回頁面時將 token 渲染到頁面上,在 form 表單提交的時候通過隱藏域或者作為查詢參數把 CSRF token 提交到服務器。比如,在同步渲染頁面時,在表單請求中增加一個 _csrf 的查詢參數,這樣當用戶在提交這個表單的時候就會將 CSRF token 提交上來:

  1. <form method="POST" action="/upload?_csrf={{由服務端生成}}" enctype="multipart/form-data"
  2.   用戶名: <input name="name" /> 
  3.   選擇頭像: <input name="file" type="file" /> 
  4.   <button type="submit">提交</button> 
  5. </form> 

4.2.3 雙重 Cookie 防御
「雙重 Cookie 防御」 就是將 token 設置在 Cookie 中,在提交(POST、PUT、PATCH、DELETE)等請求時提交 Cookie,并通過請求頭或請求體帶上 Cookie 中已設置的 token,服務端接收到請求后,再進行對比校驗。

下面我們以 jQuery 為例,來看一下如何設置 CSRF token:

  1. let csrfToken = Cookies.get('csrfToken'); 
  2.  
  3. function csrfSafeMethod(method) { 
  4.   // 以下HTTP方法不需要進行CSRF防護 
  5.   return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
  6.  
  7. $.ajaxSetup({ 
  8.   beforeSend: function(xhr, settings) { 
  9.     if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 
  10.       xhr.setRequestHeader('x-csrf-token', csrfToken); 
  11.     } 
  12.   }, 
  13. }); 

介紹完 CSRF 攻擊的方式和防御手段,最后我們來看一下 Axios 是如何防御 CSRF 攻擊的。

4.3 Axios CSRF 防御
Axios 提供了 xsrfCookieName 和 xsrfHeaderName 兩個屬性來分別設置 CSRF 的 Cookie 名稱和 HTTP 請求頭的名稱,它們的默認值如下所示:

  1. // lib/defaults.js 
  2. var defaults = { 
  3.   adapter: getDefaultAdapter(), 
  4.  
  5.   // 省略部分代碼 
  6.   xsrfCookieName: 'XSRF-TOKEN'
  7.   xsrfHeaderName: 'X-XSRF-TOKEN'
  8. }; 

前面我們已經知道在不同的平臺中,Axios 使用不同的適配器來發送 HTTP 請求,這里我們以瀏覽器平臺為例,來看一下 Axios 如何防御 CSRF 攻擊:

  1. // lib/adapters/xhr.js 
  2. module.exports = function xhrAdapter(config) { 
  3.   return new Promise(function dispatchXhrRequest(resolve, reject) { 
  4.     var requestHeaders = config.headers; 
  5.      
  6.     var request = new XMLHttpRequest(); 
  7.     // 省略部分代碼 
  8.      
  9.     // 添加xsrf頭部 
  10.     if (utils.isStandardBrowserEnv()) { 
  11.       var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ? 
  12.         cookies.read(config.xsrfCookieName) : 
  13.         undefined; 
  14.  
  15.       if (xsrfValue) { 
  16.         requestHeaders[config.xsrfHeaderName] = xsrfValue; 
  17.       } 
  18.     } 
  19.  
  20.     request.send(requestData); 
  21.   }); 
  22. }; 

看完以上的代碼,相信小伙伴們就已經知道答案了,原來 Axios 內部是使用 「雙重 Cookie 防御」 的方案來防御 CSRF 攻擊。

好的,到這里本文的主要內容都已經介紹完了,其實 Axios 項目還有一些值得我們借鑒的地方,比如 CancelToken 的設計、異常處理機制等,感興趣的小伙伴可以自行學習一下。

五、參考資源
Github - axios
維基百科 - 跨站請求偽造
Egg - 安全威脅 CSRF 的防范

 

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

2017-03-22 12:58:58

WP系統Windows動態磁貼

2017-03-20 19:12:24

WPWindows PhoOLED

2022-08-02 15:18:00

React開源項目

2015-11-10 16:13:22

數據中心節能

2009-08-03 13:02:44

Windows7VistaUbuntu

2009-12-12 11:01:30

LinuxWindows系統特性

2009-12-07 09:26:00

LinuxWindows

2023-08-14 08:34:14

GolangHttp

2022-11-30 08:17:41

JVM調優技巧

2022-05-25 14:35:57

加密貨幣比特幣以太坊

2019-10-16 08:00:00

網管員IT網絡

2020-12-24 16:56:14

首席執行官遠程工作

2020-07-14 08:45:13

Flink特性jira

2020-10-29 12:55:47

編程代碼開發

2011-01-06 09:17:10

創新HadoopSharePoint

2012-08-09 13:38:39

API

2013-12-23 15:00:14

Windows 8.2Win8.2

2022-07-18 08:00:00

邊緣計算經驗開發

2013-06-24 09:25:06

無線路由器路由器無線網絡

2014-01-16 10:01:29

虛擬運營商
點贊
收藏

51CTO技術棧公眾號

动漫av网站免费观看| 国产精选一区二区| 日本激情视频一区二区三区| 亚洲精品一区av| 亚洲一区二区三区四区的| 久久天堂国产精品| 国产精品久久免费| 亚洲一区国产| 久久人人爽人人爽人人片亚洲| 中文字幕无码毛片免费看| 日本在线啊啊| 亚洲免费观看高清| 欧美日韩三区四区| 精品国产黄色片| 丝袜诱惑制服诱惑色一区在线观看 | 26uuu亚洲伊人春色| 91无套直看片红桃在线观看| 哺乳挤奶一区二区三区免费看| 欧美自拍偷拍一区| aa视频在线播放| 尤物网在线观看| 99在线视频精品| 91啪国产在线| 无码人妻精品一区二区| 欧美日韩综合| 日韩视频第一页| 色欲狠狠躁天天躁无码中文字幕| 黄色美女久久久| 日韩三级av在线播放| 中文字幕国内自拍| 成人在线黄色电影| 亚洲一区二区三区三| 亚洲精品中文字幕在线| 天天影院图片亚洲| 不卡一区二区中文字幕| 69174成人网| 国产精品特级毛片一区二区三区| 蜜桃视频一区| 全球成人中文在线| wwwxxx亚洲| 最新亚洲一区| 欧美激情欧美激情在线五月| 三级在线观看免费大全| 久久人体视频| 色偷偷噜噜噜亚洲男人| 在线观看亚洲大片短视频| 亚洲人成精品久久久| 亚洲精品狠狠操| 精品人妻一区二区三区日产| 国产厕拍一区| 亚洲国产成人在线视频| a级片在线观看视频| 2021年精品国产福利在线| 日韩一区二区在线播放| 国产伦精品一区二区三区妓女下载| 久久av影院| 欧美精品v日韩精品v韩国精品v| www.99av.com| 日韩国产一二三区| 欧美一区二区视频在线观看 | 2023国产精华国产精品| 欧美成人综合网站| 亚洲麻豆一区二区三区| 高清精品xnxxcom| 精品视频久久久久久| 草草影院第一页| 精品国产一区二区三区久久久蜜臀 | 91大片在线观看| 亚洲xxx在线| 99精品国产一区二区三区不卡| 精品国产乱码久久久久久郑州公司 | 中文字幕成人| 日韩精品一区二区三区中文不卡 | 国产一区二区自拍视频| 国产在线播放一区三区四| 91黄在线观看| 天天摸天天碰天天爽天天弄| 久久欧美中文字幕| 伊人色综合影院| 女囚岛在线观看| 精品久久久中文| 免费看污黄网站| 玖玖玖电影综合影院| 亚洲国产精品女人久久久| 一级黄色性视频| 午夜精品视频一区二区三区在线看| 欧美成人激情视频| 日本韩国欧美中文字幕| 久久99精品一区二区三区三区| 91久色国产| 国产特黄在线| 亚洲精品成人a在线观看| 中国丰满人妻videoshd | av一区观看| 男女网站在线观看| 亚洲欧美一区二区三区国产精品| 激情五月宗合网| 91麻豆精品| 日韩成人网免费视频| 亚洲AV成人无码网站天堂久久| 欧美精品大片| 日韩av手机在线看| 亚洲第一精品网站| 国产精品美女视频| 久久成人免费观看| 国产精品国产亚洲精品| 精品一区二区电影| 91精品国产闺蜜国产在线闺蜜| 一本综合久久| 成人精品一二区| 2021av在线| 欧美视频免费在线观看| 国产男女无遮挡猛进猛出| 九九综合在线| 午夜精品一区二区三区在线 | 成人白浆超碰人人人人| 亚洲欧洲日韩综合二区| 福利在线免费视频| 日韩欧美电影一二三| 成人午夜免费影院| 久久久久久久高潮| 精品不卡一区二区三区| 2024短剧网剧在线观看| 欧美日本乱大交xxxxx| 性色av蜜臀av色欲av| 激情综合网址| 91嫩草在线视频| 色网站免费在线观看| 在线观看免费视频综合| 人妻丰满熟妇av无码久久洗澡 | 国产三区四区在线观看| 激情久久av一区av二区av三区| 国产5g成人5g天天爽| 欧美三级伦理在线| 国产精品久久久久久久久久久久久久 | 久久在线观看视频| 一级黄色免费看| 国产精品久久久久影院| 冲田杏梨av在线| 成人vr资源| 国产成人精品一区二区| 欧美性孕妇孕交| 日韩欧美亚洲综合| 无套内谢大学处破女www小说| 欧美日韩三区| 不卡视频一区二区三区| av中文在线资源| 精品久久久久久亚洲综合网 | 黑人与娇小精品av专区| 一级特黄a大片免费| aa国产精品| 精品欧美日韩在线| 免费在线小视频| 精品视频www| 国产又粗又猛又爽又| 欧美激情在线看| 免费成年人高清视频| 亚洲国产老妈| 国产另类第一区| 国产精品13p| 亚洲无限av看| 一本色道久久综合亚洲| 最新中文字幕一区二区三区| 国模大尺度视频| 欧美在线三级| 狠狠色综合一区二区| www.youjizz.com在线| 亚洲精品在线看| 中文字字幕在线中文乱码| 日韩理论片网站| 国产一精品一aⅴ一免费| 亚洲一本视频| 欧美中日韩免费视频| 久久伊人国产| 欧美黑人巨大xxx极品| 天堂av在线免费观看| 精品视频1区2区| 久久久久成人网站| 久久综合99re88久久爱| 污污动漫在线观看| 韩国亚洲精品| 丝袜足脚交91精品| 欧洲精品99毛片免费高清观看| 91国产视频在线播放| 二区在线观看| 精品国产乱码久久久久久浪潮| 懂色av蜜臀av粉嫩av分享吧最新章节| 国产精品久久久一本精品| 少妇欧美激情一区二区三区| 亚洲欧美久久久| 椎名由奈jux491在线播放| 大型av综合网站| 国产女同一区二区| 黄色软件视频在线观看| 色七七影院综合| 亚洲 欧美 精品| 91精品国产色综合久久不卡电影| 国产午夜视频在线| 亚洲欧洲色图综合| 亚洲欧美视频在线播放| 国产一区在线观看视频| 久久精品国产精品亚洲色婷婷| 亚洲精品成人影院| 欧美主播一区二区三区美女 久久精品人 | 日韩欧美在线视频免费观看| 男女羞羞免费视频| 亚洲国产成人自拍| 爱爱的免费视频| 成人av资源在线观看| 一本色道久久亚洲综合精品蜜桃| 亚洲国产一区二区三区a毛片| 欧美爱爱视频网站| 免费看成人哺乳视频网站| 成人一区二区在线| www 久久久| 国产精品一久久香蕉国产线看观看| av蜜臀在线| 欧美成人免费全部| 在线日本中文字幕| 亚洲人午夜色婷婷| 五月婷婷激情在线| 亚洲精品一区二区在线观看| 伊人22222| 欧美丝袜丝交足nylons图片| 日本特级黄色片| 亚洲va天堂va国产va久| 欧美日韩三级在线观看| 综合激情成人伊人| 国产精品1区2区3区4区| 国产无人区一区二区三区| 亚洲自拍偷拍一区二区| 91麻豆123| 日韩精品视频一区二区| 成人性色生活片| 日本人dh亚洲人ⅹxx| 国产麻豆精品一区二区| www.51色.com| 国产精品亚洲专一区二区三区| 亚洲欧美手机在线| 久久精品国产久精国产爱| 国产一区二区在线免费播放| 日韩精品福利网| 在线视频日韩一区| 美女视频黄a大片欧美| 日本免费观看网站| 蜜芽一区二区三区| 五月花丁香婷婷| 国产在线观看一区二区| 337p日本欧洲亚洲大胆张筱雨 | 五月天婷婷色综合| 亚洲精品欧美激情| 精品99久久久久成人网站免费 | 538任你躁精品视频网免费| 91久久极品少妇xxxxⅹ软件| 亚洲一区二区三区在线免费| 97人摸人人澡人人人超一碰| 91精品久久久久久综合五月天| 99免费在线视频观看| 久久精品66| 欧美高清一区二区| 欧洲杯什么时候开赛| 亚洲乱码一区二区三区| 天天影视综合| 日韩一级免费看| 亚洲清纯自拍| 国产黄色特级片| 麻豆91在线观看| 男人操女人下面视频| 风流少妇一区二区| 国产亚洲无码精品| 国产精品福利一区二区三区| 国产精品成人免费观看| 亚洲成av人**亚洲成av**| 9i看片成人免费看片| 欧美午夜一区二区三区免费大片| 国产又粗又猛又黄又爽| 亚洲大胆人体在线| 国产主播福利在线| 欧美乱妇40p| 成人影院大全| 成人性教育视频在线观看| 国产成人aa在线观看网站站| 日日夜夜精品网站| 欧美精品三级| 国产淫片av片久久久久久| 看国产成人h片视频| 免费在线观看日韩av| 久久色视频免费观看| 波多野结衣亚洲一区二区| 午夜国产精品一区| 91中文字幕在线播放| 亚洲精品第一国产综合精品| 最新av网站在线观看| 国内外成人免费激情在线视频| 日韩另类视频| 国产亚洲欧美一区二区| 第一会所sis001亚洲| 无码人妻精品一区二区蜜桃网站| 久久久蜜桃一区二区人| 亚洲自拍第三页| 久久精品一区八戒影视| 欧美又粗又大又长| 欧美体内she精视频| 污视频网站免费观看| xvideos亚洲人网站| 丝袜诱惑一区二区| av噜噜色噜噜久久| 亚洲成人三区| 成人一区二区三| 99国产精品久久久| 久久国产一级片| 欧美精品 国产精品| 国产资源在线播放| 国产91av在线| 99香蕉久久| 一区二区三区四区免费观看| 日韩av网站在线观看| 青青草视频成人| 性做久久久久久免费观看| 北条麻妃一二三区| 久久在线免费观看视频| 国产精成人品2018| 天堂va久久久噜噜噜久久va| 亚洲综合精品四区| 国产精品久久久久久久无码| 亚洲一区二区三区爽爽爽爽爽| 国产精品无码久久久久成人app| 亚洲色图美腿丝袜| 最近高清中文在线字幕在线观看1| 国产精品播放| 欧美午夜国产| 岛国大片在线免费观看| 亚洲日本成人在线观看| 91一区二区视频| 久久久精品免费| 国产在线一区不卡| 国产精品av免费观看| 国产一区二三区| 欧美日韩在线国产| 精品久久久久久久人人人人传媒 | 色婷婷av一区二区三区之一色屋| 蜜臀久久精品久久久久| 欧美激情网友自拍| 粉嫩一区二区三区四区公司1| 国产曰肥老太婆无遮挡| 丁香桃色午夜亚洲一区二区三区| 青青操国产视频| 精品欧美乱码久久久久久1区2区| 久久不射影院| 高清av免费一区中文字幕| 在线欧美不卡| 精品久久久久久中文字幕人妻最新| 狠狠色狠狠色综合日日小说| 欧美日韩国产综合视频| 国产精品成熟老女人| 色婷婷一区二区三区| 中文字幕色网站| 亚洲最快最全在线视频| 色婷婷在线视频| 国产成人在线视频| 欧美国产一级| 日本中文字幕精品| 岛国av一区二区在线在线观看| 黄网在线免费| 91精品视频专区| 精久久久久久| 男人操女人动态图| 欧美日韩一区高清| 欧美hdxxx| 欧美一区二区三区精美影视 | 草草地址线路①屁屁影院成人| 日本韩国欧美三级| 欧美激情办公室videoshd| y111111国产精品久久婷婷| 国产亚洲在线| 亚洲精品电影院| 亚洲第一页自拍| 亚洲成人一区在线观看| 欧美与动交zoz0z| 99久久99久久免费精品蜜臀| 少妇一级淫片日本| 久久久久国产精品免费网站| 一区二区美女| 色婷婷综合在线观看| 欧美性69xxxx肥| 黄色免费网站在线| 精品免费国产| 国产一区二区电影| 免费av网站在线| 欧美大尺度激情区在线播放| 亚欧日韩另类中文欧美| 亚洲欧美日本一区二区三区| 性做久久久久久久久| jizz在线观看中文| 国产午夜精品在线| 久久爱www久久做| 国产成人免费看| 欧美日韩第一页| 日韩在线观看电影完整版高清免费悬疑悬疑 | 久草精品视频在线观看|