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

熱點推薦:前后端分離了,然后呢?

開發(fā) 項目管理
前后端分離是一件容易的事情,而且團隊可能在短期可以看到很多好處,但是如果不認真處理集成的問題,分離反而可能會帶來更長的集成時間。通過面向契約的方式來組織各自的測試,可以帶來很多的好處:更快速的End2End測試,更平滑的集成,更安全的分離開發(fā)等等。

前言

前后端分離已經(jīng)是業(yè)界所共識的一種開發(fā)/部署模式了。所謂的前后端分離,并不是傳統(tǒng)行業(yè)中的按部門劃分,一部分人純做前端(HTML/CSS /JavaScript/Flex),另一部分人純做后端,因為這種方式是不工作的:比如很多團隊采取了后端的模板技術(shù)(JSP, FreeMarker, ERB等等),前端的開發(fā)和調(diào)試需要一個后臺Web容器的支持,從而無法做到真正的分離(更不用提在部署的時候,由于動態(tài)內(nèi)容和靜態(tài)內(nèi)容混在一起,當設(shè)計 動態(tài)靜態(tài)分流的時候,處理起來非常麻煩)。關(guān)于前后端開發(fā)的另一個討論可以參考這里。

即使通過API來解耦前端和后端開發(fā)過程,前后端通過RESTFul的接口來通信,前端的靜態(tài)內(nèi)容和后端的動態(tài)計算分別開發(fā),分別部署,集成仍然 是一個繞不開的問題 — 前端/后端的應(yīng)用都可以獨立的運行,但是集成起來卻不工作。我們需要花費大量的精力來調(diào)試,直到上線前仍然沒有人有信心所有的接口都是工作的。

一點背景

一個典型的Web應(yīng)用的布局看起來是這樣的:

前后端都各自有自己的開發(fā)流程,構(gòu)建工具,測試集合等等。前后端僅僅通過接口來編程,這個接口可能是JSON格式的RESTFul的接口,也可能 是XML的,重點是后臺只負責數(shù)據(jù)的提供和計算,而完全不處理展現(xiàn)。而前端則負責拿到數(shù)據(jù),組織數(shù)據(jù)并展現(xiàn)的工作。這樣結(jié)構(gòu)清晰,關(guān)注點分離,前后端會變 得相對獨立并松耦合。

上述的場景還是比較理想,我們事實上在實際環(huán)境中會有非常復雜的場景,比如異構(gòu)的網(wǎng)絡(luò),異構(gòu)的操作系統(tǒng)等等:

在實際的場景中,后端可能還會更復雜,比如用C語言做數(shù)據(jù)采集,然后通過Java整合到一個數(shù)據(jù)倉庫,然后該數(shù)據(jù)倉庫又有一層Web Service,***若干個這樣的Web Service又被一個Ruby的聚合Service整合在一起返回給前端。在這樣一個復雜的系統(tǒng)中,后臺任意端點的失敗都可能阻塞前端的開發(fā)流程,因此 我們會采用mock的方式來解決這個問題:

這個mock服務(wù)器可以啟動一個簡單的HTTP服務(wù)器,然后將一些靜態(tài)的內(nèi)容serve出來,以供前端代碼使用。這樣的好處很多:

1.前后端開發(fā)相對獨立

2.后端的進度不會影響前端開發(fā)

3.啟動速度更快

4.前后端都可以使用自己熟悉的技術(shù)棧(讓前端的學maven,讓后端的用gulp都會很不順手)

但是當集成依然是一個令人頭疼的難題。我們往往在集成的時候才發(fā)現(xiàn),本來協(xié)商的數(shù)據(jù)結(jié)構(gòu)變了:deliveryAddress字段本來是一個字符 串,現(xiàn)在變成數(shù)組了(業(yè)務(wù)發(fā)生了變更,系統(tǒng)現(xiàn)在可以支持多個快遞地址);price字段變成字符串,協(xié)商的時候是number;用戶郵箱地址多了一個層級 等等。這些變動在所難免,而且時有發(fā)生,這會花費大量的調(diào)試時間和集成時間,更別提修改之后的回歸測試了。

所以僅僅使用一個靜態(tài)服務(wù)器,然后提供mock數(shù)據(jù)是遠遠不夠的。我們需要的mock應(yīng)該還能做到:

1.前端依賴指定格式的mock數(shù)據(jù)來進行UI開發(fā)

2.前端的開發(fā)和測試都基于這些mock數(shù)據(jù)

3.后端產(chǎn)生指定格式的mock數(shù)據(jù)

4.后端需要測試來確保生成的mock數(shù)據(jù)正是前端需要的

簡而言之,我們需要商定一些契約,并將這些契約作為可以被測試的中間格式。然后前后端都需要有測試來使用這些契約。一旦契約發(fā)生變化,則另一方的測試會失敗,這樣就會驅(qū)動雙方協(xié)商,并降低集成時的浪費。

一個實際的場景是:前端發(fā)現(xiàn)已有的某個契約中,缺少了一個address的字段,于是就在契約中添加了該字段。然后在UI上將這個字段正確的展現(xiàn) 了(當然還設(shè)置了字體,字號,顏色等等)。但是后臺生成該契約的服務(wù)并沒有感知到這一變化,當運行生成契約部分測試(后臺)時,測試會失敗了 — 因為它并沒有生成這個字段。于是后端工程師就找前端來商量,了解業(yè)務(wù)邏輯之后,他會修改代碼,并保證測試通過。這樣,當集成的時候,就不會出現(xiàn)UI上少了 一個字段,但是誰也不知道是前端問題,后端問題,還是數(shù)據(jù)庫問題等。

而且實際的項目中,往往都是多個頁面,多個API,多個版本,多個團隊同時進行開發(fā),這樣的契約會降低非常多的調(diào)試時間,使得集成相對平滑。

在實踐中,契約可以定義為一個JSON文件,或者一個XML的payload。只需要保證前后端共享同一個契約集合來做測試,那么集成工作就會從 中受益。一個最簡單的形式是:提供一些靜態(tài)的mock文件,而前端所有發(fā)往后臺的請求都被某種機制攔截,并轉(zhuǎn)換成對該靜態(tài)資源的請求。

1.moco,基于Java

2.wiremock,基于Java

3.sinatra,基于Ruby

看到sinatra被列在這里,可能熟悉Ruby的人會反對:它可是一個后端全功能的的程序庫啊。之所以列它在這里,是因為sinatra提供了 一套簡潔優(yōu)美的DSL,這個DSL非常契合Web語言,我找不到更漂亮的方式來使得這個mock server更加易讀,所以就采用了它。

#p#

一個例子

我們以這個應(yīng)用為示例,來說明如何在前后端分離之后,保證代碼的質(zhì)量,并降低集成的成本。這個應(yīng)用場景很簡單:所有人都可以看到一個條目列表,每個登陸用戶都可以選擇自己喜歡的條目,并為之加星。加星之后的條目會保存到用戶自己的個人中心中。用戶界面看起來是這樣的:

不過為了專注在我們的中心上,我去掉了諸如登陸,個人中心之類的頁面,假設(shè)你是一個已登錄用戶,然后我們來看看如何編寫測試。

前端開發(fā)

根據(jù)通常的做法,前后端分離之后,我們很容易mock一些數(shù)據(jù)來自己測試:

Js代碼

     

    1.     { 
    2.         "id"1
    3.         "url""http://abruzzi.github.com/2015/03/list-comprehension-in-python/"
    4.         "title""Python中的 list comprehension 以及 generator"
    5.         "publicDate""2015年3月20日" 
    6.     }, 
    7.     { 
    8.         "id"2
    9.         "url""http://abruzzi.github.com/2015/03/build-monitor-script-based-on-inotify/"
    10.         "title""使用inotify/fswatch構(gòu)建自動監(jiān)控腳本"
    11.         "publicDate""2015年2月1日" 
    12.     }, 
    13.     { 
    14.         "id"3
    15.         "url""http://abruzzi.github.com/2015/02/build-sample-application-by-using-underscore-and-jquery/"
    16.         "title""使用underscore.js構(gòu)建前端應(yīng)用"
    17.         "publicDate""2015年1月20日" 
    18.     } 

然后,一個可能的方式是通過請求這個json來測試前臺:

Js代碼

     

    1. $(function() { 
    2.   $.get('/mocks/feeds.json').then(function(feeds) { 
    3.       var feedList = new Backbone.Collection(extended); 
    4.       var feedListView = new FeedListView(feedList); 
    5.  
    6.       $('.container').append(feedListView.render()); 
    7.   }); 
    8. }); 

這樣當然是可以工作的,但是這里發(fā)送請求的url并不是最終的,當集成的時候我們又需要修改為真實的url。一個簡單的做法是使用Sinatra來做一次url的轉(zhuǎn)換:

Js代碼

  1. get '/api/feeds' do 
  2.   content_type 'application/json' 
  3.   File.open('mocks/feeds.json').read 
  4. end 

這樣,當我們和實際的服務(wù)進行集成時,只需要連接到那個服務(wù)器就可以了。

注意,我們現(xiàn)在的核心是mocks/feeds.json這個文件。這個文件現(xiàn)在的角色就是一個契約,至少對于前端來說是這樣的。緊接著,我們的應(yīng)用需要渲染加星的功能,這就需要另外一個契約:找出當前用戶加星過的所有條目,因此我們加入了一個新的契約:

Js代碼

     

    1.     { 
    2.         "id"3
    3.         "url""http://abruzzi.github.com/2015/02/build-sample-application-by-using-underscore-and-jquery/"
    4.         "title""使用underscore.js構(gòu)建前端應(yīng)用"
    5.         "publicDate""2015年1月20日" 
    6.     } 

然后在sinatra中加入一個新的映射:

Js代碼

     

    1. get '/api/fav-feeds/:id' do 
    2.   content_type 'application/json' 
    3.   File.open('mocks/fav-feeds.json').read 
    4. end 

通過這兩個請求,我們會得到兩個列表,然后根據(jù)這兩個列表的交集來繪制出所有的星號的狀態(tài)(有的是空心,有的是實心):

Js代碼

    1. $.when(feeds, favorite).then(function(feeds, favorite) { 
    2.     var ids = _.pluck(favorite[0], 'id'); 
    3.     var extended = _.map(feeds[0], function(feed) { 
    4.         return _.extend(feed, {status: _.includes(ids, feed.id)}); 
    5.     }); 
    6.  
    7.     var feedList = new Backbone.Collection(extended); 
    8.     var feedListView = new FeedListView(feedList); 
    9.  
    10.     $('.container').append(feedListView.render()); 
    11. }); 

剩下的一個問題是當點擊紅心時,我們需要發(fā)請求給后端,然后更新紅心的狀態(tài):

Js代碼

 

  1. toggleFavorite: function(event) { 
  2.     event.preventDefault(); 
  3.     var that = this
  4.     $.post('/api/feeds/'+this.model.get('id')).done(function(){ 
  5.         var status = that.model.get('status'); 
  6.         that.model.set('status', !status); 
  7.     }); 

這里又多出來一個請求,不過使用Sinatra我們還是可以很容易的支持它:

Js代碼

     

    1. post '/api/feeds/:id' do 
    2. end 

可以看到,在沒有后端的情況下,我們一切都進展順利 — 后端甚至還沒有開始做,或者正在由一個進度比我們慢的團隊在開發(fā),不過無所謂,他們不會影響我們的。

不僅如此,當我們寫完前端的代碼之后,可以做一個End2End的測試。由于使用了mock數(shù)據(jù),免去了數(shù)據(jù)庫和網(wǎng)絡(luò)的耗時,這個End2End的測試會運行的非常快,并且它確實起到了端到端的作用。這些測試在***的集成時,還可以用來當UI測試來運行。所謂一舉多得。

Js代碼

     

    1. #encoding: utf-8 
    2. require 'spec_helper' 
    3.  
    4. describe 'Feeds List Page' do 
    5.   let(:list_page) {FeedListPage.new
    6.  
    7.   before do 
    8.       list_page.load 
    9.   end 
    10.  
    11.   it 'user can see a banner and some feeds' do 
    12.       expect(list_page).to have_banner 
    13.       expect(list_page).to have_feeds 
    14.   end 
    15.  
    16.   it 'user can see 3 feeds in the list' do 
    17.       expect(list_page.all_feeds).to have_feed_items count: 3 
    18.   end 
    19.  
    20.   it 'feed has some detail information' do 
    21.       first = list_page.all_feeds.feed_items.first 
    22.       expect(first.title).to eql("Python中的 list comprehension 以及 generator"
    23.   end 
    24. end 

關(guān)于如何編寫這樣的測試,可以參考之前寫的這篇文章

#p#

后端開發(fā)

我在這個示例中,后端采用了spring-boot作為示例,你應(yīng)該可以很容易將類似的思路應(yīng)用到Ruby或者其他語言上。

首先是請求的入口,F(xiàn)eedsController會負責解析請求路徑,查數(shù)據(jù)庫,***返回JSON格式的數(shù)據(jù)。

Js代碼

     

    1. @Controller 
    2. @RequestMapping("/api"
    3. public class FeedsController { 
    4.  
    5.     @Autowired 
    6.     private FeedsService feedsService; 
    7.  
    8.     @Autowired 
    9.     private UserService userService; 
    10.  
    11.     public void setFeedsService(FeedsService feedsService) { 
    12.         this.feedsService = feedsService; 
    13.     } 
    14.  
    15.     public void setUserService(UserService userService) { 
    16.         this.userService = userService; 
    17.     } 
    18.  
    19.     @RequestMapping(value="/feeds", method = RequestMethod.GET) 
    20.     @ResponseBody 
    21.     public Iterable<Feed> allFeeds() { 
    22.         return feedsService.allFeeds(); 
    23.     } 
    24.  
    25.  
    26.     @RequestMapping(value="/fav-feeds/{userId}", method = RequestMethod.GET) 
    27.     @ResponseBody 
    28.     public Iterable<Feed> favFeeds(@PathVariable("userId") Long userId) { 
    29.         return userService.favoriteFeeds(userId); 
    30.     } 

具體查詢的細節(jié)我們就不做討論了,感興趣的可以在文章結(jié)尾處找到代碼庫的鏈接。那么有了這個Controller之后,我們?nèi)绾螠y試它呢?或者說,如何讓契約變得實際可用呢?

sprint-test提供了非常優(yōu)美的DSL來編寫測試,我們僅需要一點代碼就可以將契約用起來,并實際的監(jiān)督接口的修改:

Js代碼

  1. private MockMvc mockMvc; 
  2. private FeedsService feedsService; 
  3. private UserService userService; 
  4.  
  5. @Before 
  6. public void setup() { 
  7.     feedsService = mock(FeedsService.class); 
  8.     userService = mock(UserService.class); 
  9.  
  10.     FeedsController feedsController = new FeedsController(); 
  11.     feedsController.setFeedsService(feedsService); 
  12.     feedsController.setUserService(userService); 
  13.  
  14.     mockMvc = standaloneSetup(feedsController).build(); 
建立了mockmvc之后,我們就可以編寫Controller的單元測試了:

Js代碼

     

    1. @Test 
    2. public void shouldResponseWithAllFeeds() throws Exception { 
    3.     when(feedsService.allFeeds()).thenReturn(Arrays.asList(prepareFeeds())); 
    4.  
    5.     mockMvc.perform(get("/api/feeds")) 
    6.             .andExpect(status().isOk()) 
    7.             .andExpect(content().contentType("application/json;charset=UTF-8")) 
    8.             .andExpect(jsonPath("$", hasSize(3))) 
    9.             .andExpect(jsonPath("$[0].publishDate", is(notNullValue()))); 

當發(fā)送GET請求到/api/feeds上之后,我們期望返回狀態(tài)是200,然后內(nèi)容是application/json。然后我們預期返回的結(jié)果是一個長度為3的數(shù)組,然后數(shù)組中的***個元素的publishDate字段不為空。

注意此處的prepareFeeds方法,事實上它會去加載mocks/feeds.json文件 — 也就是前端用來測試的mock文件:

Js代碼

  1. private Feed[] prepareFeeds() throws IOException { 
  2.     URL resource = getClass().getResource("/mocks/feeds.json"); 
  3.     ObjectMapper mapper = new ObjectMapper(); 
  4.     return mapper.readValue(resource, Feed[].class); 

這樣,當后端修改Feed定義(添加/刪除/修改字段),或者修改了mock數(shù)據(jù)等,都會導致測試失敗;而前端修改mock之后,也會導致測試失敗 — 不要懼怕失敗 — 這樣的失敗會促進一次協(xié)商,并驅(qū)動出最終的service的契約。

對應(yīng)的,測試/api/fav-feeds/{userId}的方式類似:

Js代碼

     

    1. @Test 
    2. public void shouldResponseWithUsersFavoriteFeeds() throws Exception { 
    3.     when(userService.favoriteFeeds(any(Long.class))) 
    4.         .thenReturn(Arrays.asList(prepareFavoriteFeeds())); 
    5.  
    6.     mockMvc.perform(get("/api/fav-feeds/1")) 
    7.             .andExpect(status().isOk()) 
    8.             .andExpect(content().contentType("application/json;charset=UTF-8")) 
    9.             .andExpect(jsonPath("$", hasSize(1))) 
    10.             .andExpect(jsonPath("$[0].title", is("使用underscore.js構(gòu)建前端應(yīng)用"))) 
    11.             .andExpect(jsonPath("$[0].publishDate", is(notNullValue()))); 

總結(jié)

前后端分離是一件容易的事情,而且團隊可能在短期可以看到很多好處,但是如果不認真處理集成的問題,分離反而可能會帶來更長的集成時間。通過面向契約的方式來組織各自的測試,可以帶來很多的好處:更快速的End2End測試,更平滑的集成,更安全的分離開發(fā)等等。

代碼

前后端的代碼我都放到了Gitbub上,感興趣的可以clone下來自行研究:

1.bookmarks-frontend

2.bookmarks-server

責任編輯:王雪燕 來源: IT技術(shù)精華
相關(guān)推薦

2018-10-17 11:30:02

前后端代碼接口

2019-06-12 19:00:14

前后端分離AppJava

2023-02-08 16:29:58

前后端開發(fā)

2021-01-09 23:08:45

架構(gòu)前端后端

2021-09-18 09:45:33

前端接口架構(gòu)

2017-03-13 11:04:24

后端開發(fā)

2019-07-09 05:44:35

前后端分離架構(gòu)接口規(guī)范

2020-09-25 11:50:12

前后端分離架構(gòu)Web

2021-10-20 18:21:18

項目技術(shù)開發(fā)

2014-04-18 14:43:07

前后端分離NodeJS

2017-02-15 10:18:32

架構(gòu)前后端分離

2022-04-06 07:50:57

JWT后端Spring

2019-12-04 08:44:59

前后端分離開發(fā)

2017-11-15 07:01:33

互聯(lián)網(wǎng)分層架構(gòu)前后端

2016-08-22 13:31:05

前端架構(gòu)前后端分離

2016-09-21 10:11:19

2022-05-27 10:40:04

前后端權(quán)限控制設(shè)計

2021-06-16 08:05:14

centos nginx 后端

2022-09-01 07:18:21

分離項目Vue

2017-11-06 08:41:53

互聯(lián)網(wǎng)分層架構(gòu)前后端
點贊
收藏

51CTO技術(shù)棧公眾號

日韩成人精品在线观看| 理论片一区二区在线| 成人免费小视频| 超碰97在线人人| 天天干天天干天天| 久久高清精品| 亚洲精品久久久久久久久久久久 | 日本不卡一区二区三区视频| 一区二区日韩在线观看| 亚洲美女毛片| 超薄丝袜一区二区| 日本黄色网址大全| 亚洲日本视频在线| 欧美视频一二三区| 国产精品网站免费| 黄网站在线免费看| 国产亚洲午夜高清国产拍精品| 成人伊人精品色xxxx视频| 色屁屁影院www国产高清麻豆| 99久久99热这里只有精品| 日韩精品在线观看视频| 男插女视频网站| 国产精品久久久久久久久免费高清| 亚洲综合视频在线观看| 中文字幕在线亚洲三区| 国产乱理伦片a级在线观看| 国产成人鲁色资源国产91色综| 国产精品高清网站| 国产又大又黄视频| 亚洲精品裸体| 欧美国产视频一区二区| 国产天堂av在线| 日韩黄色大片网站| 亚洲精品永久免费| 免费无码一区二区三区| jazzjazz国产精品麻豆| 欧美一区二区啪啪| 孩娇小videos精品| 欧洲精品一区二区三区| 色哟哟亚洲精品| 青青青免费在线| 国产三线在线| 亚洲一区二区黄色| 日b视频免费观看| 成人午夜在线影视| 最近中文字幕一区二区三区| 中文字幕剧情在线观看一区| 3d成人动漫在线| 中文一区二区在线观看| 日韩亚洲视频在线| 国产98在线| 国产日韩欧美高清在线| 台湾成人av| 三区四区在线视频| 亚洲色图另类专区| 国产一区 在线播放| 麻豆av在线播放| 亚洲成人午夜影院| 精品无码一区二区三区在线| 亚洲少妇视频| 日本精品免费观看高清观看| 成年人在线看片| 青青热久免费精品视频在线18| 在线视频亚洲一区| 99re精彩视频| 久久av网站| 日韩精品一区国产麻豆| 亚洲啪av永久无码精品放毛片| 超碰精品在线观看| 亚洲精品一区中文字幕乱码| 人人爽人人爽人人片| 欧美freesextv| 欧美成年人网站| 国产无遮挡裸体免费视频| 国产一区二区精品| 国产精品欧美在线| 国产丰满果冻videossex| 波多野结衣中文一区| 欧美日韩视频在线一区二区观看视频 | 日韩123区| 精品久久久香蕉免费精品视频| 国产91在线视频观看| 亚洲欧美在线成人| 日韩一区二区不卡| 国产成人无码一区二区在线观看| 亚洲v天堂v手机在线| 日韩有码在线播放| 国产精品成人免费一区二区视频| 狂野欧美一区| 51国偷自产一区二区三区| 日本黄色一区二区三区| 日本一区二区三区dvd视频在线| 一区二区三区四区欧美日韩| 宅男网站在线免费观看| 欧美性感美女h网站在线观看免费| 美女喷白浆视频| 亚洲1区在线| 亚洲性夜色噜噜噜7777| 99视频只有精品| 欧美一级专区| 99re国产| 尤物视频在线免费观看| 五月婷婷激情综合| 亚洲第一成肉网| 亚洲调教一区| 久久久久久久999精品视频| 精品一区二三区| 成人毛片老司机大片| 四虎影视永久免费在线观看一区二区三区| 污的网站在线观看| 欧美日韩在线一区二区| 亚洲精品乱码久久久久久久| 一区二区三区在线| 国产精品成人国产乱一区| 国产18精品乱码免费看| 亚洲欧洲99久久| aaa毛片在线观看| 国产精品极品国产中出| 精品国产一区久久久| 久久国产视频一区| 成人一区二区三区中文字幕| 中文字幕av导航| 日韩成人动漫| 精品视频偷偷看在线观看| 久久久国产精华液| 精品影院一区二区久久久| 日本视频一区在线观看| 正在播放日韩精品| 亚洲国产欧美日韩精品| 欧美成人手机视频| 久久精品久久综合| 亚洲高清视频一区| 午夜无码国产理论在线| 亚洲无限av看| 无码人妻丰满熟妇精品区| 91视视频在线观看入口直接观看www | 天天综合网 天天综合色| 国产吃瓜黑料一区二区| 这里只有精品在线| 亚洲一区二区中文字幕| 黄色网在线看| 777午夜精品免费视频| 日韩精品123区| 黑人精品欧美一区二区蜜桃| 一区精品在线| 麻豆一区在线| 欧美激情在线有限公司| 免费观看国产精品| 亚洲不卡在线观看| 水蜜桃av无码| 久久精品30| 日韩亚洲视频在线| 福利视频一区| 欧美精品一本久久男人的天堂| av 一区二区三区| 一个色综合网站| 性猛交╳xxx乱大交| 亚洲精选在线| 免费国产在线精品一区二区三区| 午夜无码国产理论在线| 色噜噜狠狠狠综合曰曰曰| 国产美女无遮挡永久免费| 亚洲男女一区二区三区| 亚洲av无码专区在线播放中文| 亚洲黄色精品| 欧洲久久久久久| 国产激情欧美| 欧美日韩成人黄色| 天天舔天天干天天操| 色域天天综合网| www.com.av| 国产99精品在线观看| 免费看国产曰批40分钟| 国产成人黄色| 91精品在线观| 欧美极品videos大乳护士| 亚洲欧洲一区二区三区在线观看| 一二区在线观看| 一区二区欧美精品| 成年人免费观看视频网站| 日本亚洲最大的色成网站www| 免费观看中文字幕| 国偷自产视频一区二区久| 国产成人精品一区二区在线| 久操视频在线| 精品伊人久久97| 国产又黄又粗又猛又爽| 精品国产91久久久久久| 貂蝉被到爽流白浆在线观看| 粉嫩蜜臀av国产精品网站| 波多野结衣作品集| 欧美福利视频| 日韩精品一区二区三区丰满| 爱高潮www亚洲精品| 国产精品麻豆va在线播放| av在线加勒比| 久久人人爽亚洲精品天堂| 无码精品黑人一区二区三区| 欧美精品久久久久久久多人混战 | 欧美日韩在线一区二区三区| 成人免费91| 国产精品∨欧美精品v日韩精品| 综合久久2019| 中文字幕国产亚洲2019| 亚洲av电影一区| 日韩一区二区高清| 国产精品51麻豆cm传媒| 大桥未久av一区二区三区| 老司机成人免费视频| 国产午夜精品一区二区| 在线观看亚洲免费视频| 国产麻豆一精品一av一免费| av无码精品一区二区三区| 怡红院精品视频在线观看极品| 伊人久久大香线蕉成人综合网| 亚洲男人都懂第一日本| 国产精品乱子乱xxxx| 图片一区二区| 国产精品免费久久久久影院| 九九色在线视频| 久久久久日韩精品久久久男男| 日本电影在线观看网站| 亚洲性视频网址| 欧美3p视频在线观看| 精品久久久久久无| 国产suv精品一区二区69| 欧美日韩aaaaaa| 国产精品第六页| 色猫猫国产区一区二在线视频| 亚欧洲精品在线视频| 亚洲一区二区成人在线观看| 真实国产乱子伦对白在线| 成人免费小视频| 欧美另类videoxo高潮| 国产精品麻豆网站| 超碰人人干人人| 国产日韩欧美电影| 一级黄色录像毛片| 欧美激情一区二区在线| 国产三级短视频| 中文一区一区三区高中清不卡| 国产精品国产三级国产专业不 | 国产综合久久久久久久久久久久| 嫩草影院国产精品| 蜜桃视频在线观看一区| 午夜免费福利在线| 蜜桃在线一区二区三区| 制服丝袜中文字幕第一页| 国产在线播精品第三| 99热这里只有精品2| 国产成人av影院| 亚洲啪av永久无码精品放毛片 | 51精品久久久久久久蜜臀| 一区二区三区午夜| 欧美一级欧美三级在线观看| 国产高潮在线观看| 亚洲成av人影院在线观看| 日韩一级片免费| 亚洲美女www午夜| yw193.com尤物在线| 色吧影院999| 性欧美猛交videos| 97超碰蝌蚪网人人做人人爽| 88xx成人永久免费观看| 国产精品丝袜视频| 日本成人手机在线| 精品国产乱码久久久久久久软件 | 99麻豆久久久国产精品免费优播| 精品黑人一区二区三区观看时间| 久久久91精品国产一区二区精品| 五月天免费网站| 亚洲妇女屁股眼交7| 日本韩国欧美中文字幕| 欧美日韩综合一区| 国产不卡av在线播放| 日韩av一区在线观看| av资源种子在线观看| 欧美另类暴力丝袜| 黄色aa久久| 91精品久久久久久综合乱菊| h视频久久久| 亚洲成人一区二区三区| 国内自拍一区| 成人午夜激情av| 成人在线视频首页| 日本黄色激情视频| 亚洲第一福利视频在线| 在线播放亚洲精品| 亚洲国产成人爱av在线播放| 在线免费av网站| 久久久免费精品| 丁香婷婷久久| 国产综合色一区二区三区| 日韩成人a**站| 久久久性生活视频| 韩国精品久久久| 男人操女人动态图| 伊人开心综合网| 一区二区三区在线免费观看视频 | 亚洲午夜黄色| 三级视频中文字幕| 99re6这里只有精品视频在线观看| 99热在线观看精品| 欧美性色视频在线| 国产高清在线观看视频| 国产一区二区三区在线| 91九色porn在线资源| 成人性生交大片免费看视频直播| 自拍亚洲一区| 日本阿v视频在线观看| 精品在线一区二区三区| 中文字幕网站在线观看| 午夜精品久久久久影视| 国产成人精品一区二区无码呦| 在线日韩精品视频| 在线精品亚洲欧美日韩国产| 国产精品久久亚洲7777| 欧美aa国产视频| 亚洲性图一区二区| 国产人伦精品一区二区| 西西44rtwww国产精品| 欧美精品一区视频| 青青草原av在线| 亚洲va电影大全| 欧美岛国激情| 婷婷免费在线观看| 中文字幕欧美激情| 无码人妻丰满熟妇区bbbbxxxx| 亚洲精品美女在线观看| xxxcom在线观看| 国产精品久久久久久久久久直播 | 无码av免费一区二区三区试看| 亚洲不卡免费视频| 久久av资源网站| 国产乱码精品一区二区三区亚洲人 | 91精品亚洲| 91 视频免费观看| 中文字幕在线观看不卡| 一级日韩一级欧美| 色婷婷av一区二区三区久久| 欧洲美女精品免费观看视频| 亚洲人成人77777线观看| 蜜桃视频在线一区| 免费成人美女女在线观看| 欧美日本国产视频| 欧美激情办公室videoshd| 国产三级精品网站| 亚洲第一偷拍| 亚洲欧美激情一区二区三区| 一区二区三区精品在线| 色窝窝无码一区二区三区| 高清欧美性猛交| 天天躁日日躁狠狠躁欧美巨大小说 | 99超碰麻豆| 在线成人av| 日本japanese极品少妇| 在线免费一区三区| 永久av在线| 91嫩草国产在线观看| 日韩天堂av| 精品国产av无码| 欧美日韩另类一区| 91麻豆免费在线视频| 国产精品国产亚洲精品看不卡15| 99av国产精品欲麻豆| 国产精品国产三级国产专业不| 欧美老肥妇做.爰bbww| 日韩激情美女| 欧美一级二级三级| 韩国v欧美v日本v亚洲v| 九九热国产视频| 国产一区二区三区在线免费观看 | 蜜臀av一级做a爰片久久| 久热这里有精品| 亚洲精品久久久久久久久| 精品成人av| 日本一二三区视频在线| 成人av在线影院| 国产亚洲欧美日韩高清| 另类图片亚洲另类| 欧美日韩一区二区三区四区不卡| 久久久精品麻豆| 亚洲一卡二卡三卡四卡五卡| 九色在线视频| 5566中文字幕一区二区| 亚洲综合欧美| 日韩一级片av| 亚洲午夜国产成人av电影男同| 国产精品白丝久久av网站| www国产黄色| 亚洲欧美中日韩| 伦理片一区二区三区| 亚洲一区二区免费| 日本中文字幕一区二区视频| 久久久久久久久精| 在线激情影院一区| 久久超级碰碰| 国产大片一区二区三区| 在线中文字幕一区二区| 变态调教一区二区三区|