一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

理解本真的REST架構風格

  引子

  在移動互聯網、云計算迅猛發展的今天,作為一名Web開發者,如果您還沒聽說過“REST”這個buzzword,顯然已經落伍了??鋸堻c說,甚至“出了門都不好意思跟別人打招呼”。盡管如此,對于REST這個泊來品的理解,大多數人(包括一些資深的架構師)仍然停留在“盲人摸象”的階段。常常聽到各種各樣關于REST的說法,例如:有人說:“我們這套新的API決定不用Web Service(SOAP+WSDL),而是直接使用HTTP+JSON,也就是用RESTful的方式來開發。”

  不用SOAP,甚至也不用XML,就自動變成了RESTful了。還有人認為:REST與傳統的Web Service其實沒有本質區別,只是對于URI的構造方式提出了更多要求,而這些要求Web Service完全都可以實現。潛臺詞是:既生瑜,何生亮。Web Service已經足夠好了,干嘛還要再折騰什么REST。這些對于REST的不同說法,果真如此嗎?REST究竟是什么?是一種新的技術、一種新的架構、還是一種新的規范?

  對于這些問題筆者先不解答,為了深入理解REST是什么,我們需要回顧一下Web發展的最初年代,從源頭上講講REST是怎么得來的。

  Web技術發展與REST的由來

  Web(萬維網World Wide Web的簡稱)是個包羅萬象的萬花筒,不同的人從不同的角度觀察,對于Web究竟是什么會得出大不相同的觀點。作為Web開發者,我們需要從技術上來理解Web。從技術架構層面上看,Web的技術架構包括了四個基石:

  • URI
  • HTTP
  • HyperText(除了HTML外,也可以是帶有超鏈接的XML或JSON)
  • MIME

  這四個基石相互支撐,促使Web這座宏偉的大廈以幾何級數的速度發展了起來。在這四個基石之上,Web開發技術的發展可以粗略劃分成以下幾個階段:

  1. 靜態內容階段:在這個最初的階段,使用Web的主要是一些研究機構。Web由大量的靜態HTML文檔組成,其中大多是一些學術論文。Web服務器可以被看作是支持超文本的共享文件服務器
  2. CGI程序階段:在這個階段,Web服務器增加了一些編程API。通過這些API編寫的應用程序,可以向客戶端提供一些動態變化的內容。Web服務器應用程序之間的通信,通過CGI(Common Gateway Interface)協議完成,應用程序被稱作CGI程序。
  3. 腳本語言階段:在這個階段,服務器端出現了ASP、php、JSP、ColdFusion等支持Session的腳本語言技術,瀏覽器端出現了Java Applet、JavaScript等技術。使用這些技術,可以提供更加豐富的動態內容。
  4. 瘦客戶端應用階段:在這個階段,在服務器端出現了獨立于Web服務器應用服務器。同時出現了Web MVC開發模式,各種Web MVC開發框架逐漸流行,并且占據了統治地位?;谶@些框架開發的Web應用,通常都是瘦客戶端應用,因為它們是在服務器端生成全部的動態內容。
  5. RIA應用階段:在這個階段,出現了多種RIA(Rich InterNET Application)技術,大幅改善了Web應用的用戶體驗。應用最為廣泛的RIA技術是DHTML+Ajax。Ajax技術支持在不刷新頁面的情況下動態更新頁面中的局部內容。同時誕生了大量的Web前端DHTML開發庫,例如Prototype、Dojo、ExtJS、jQuery/jQuery UI等等,很多開發庫都支持單頁面應用(Single Page Application)的開發。其他的RIA技術還有Adobe公司的Flex、微軟公司的Silverlight、Sun公司的JavaFX(現在為Oracle公司所有)等等。
  6. 移動Web應用階段:在這個階段,出現了大量面向移動設備的Web應用開發技術。除了Android、ios、Windows Phone等操作系統平臺原生的開發技術之外,基于HTML5的開發技術也變得非常流行。

  從上述Web開發技術的發展過程看,Web從最初其設計者所構思的主要支持靜態文檔的階段,逐漸變得越來越動態化。Web應用的交互模式,變得越來越復雜:從靜態文檔發展到以內容為主的門戶網站、電子商務網站、搜索引擎、社交網站,再到以娛樂為主的大型多人在線游戲、手機游戲

  在互聯網行業,實踐總是走在理論的前面。Web發展到了1995年,在CGI、ASP等技術出現之后,沿用了多年、主要面向靜態文檔的HTTP/1.0協議已經無法滿足Web應用的開發需求,因此需要設計新版本的HTTP協議。在HTTP/1.0協議專家組之中,有一位年輕人脫穎而出,顯示出了不凡的洞察力,后來他成為了HTTP/1.1協議專家組的負責人。這位年輕人就是Apache HTTP服務器的核心開發者Roy Fielding,他還是Apache軟件基金會的合作創始人。

  Roy Fielding和他的同事們在HTTP/1.1協議的設計工作中,對于Web之所以取得巨大成功,在技術架構方面的因素做了一番深入的總結。Fielding將這些總結納入到了一套理論框架之中,然后使用這套理論框架中的指導原則,來指導HTTP/1.1協議的設計方向。HTTP/1.1協議的第一個草稿是在1996年1月發布的,經過了三年多時間的修訂,于1999年6月成為了IETF的正式規范(包括了RFC 2616以及用于對客戶端做身份認證的RFC 2617)。

  HTTP/1.1協議設計的極為成功,以至于發布之后整整10年時間里,都沒有多少人認為有修訂的必要。用來指導HTTP/1.1協議設計的這套理論框架,最初是以備忘錄的形式在專家組成員之間交流,除了IETF/W3C的專家圈子,并沒有在外界廣泛流傳。Fielding在完成HTTP/1.1協議的設計工作之后,回到了加州大學歐文分校繼續攻讀自己的博士學位。第二年(2000年)在他的博士學位論文Architectural Styles and the Design of NETwork-based Software Architectures中,Fielding更為系統、嚴謹地闡述了這套理論框架,并且使用這套理論框架推導出了一種新的架構風格,并且為這種架構風格取了一個令人輕松愉快的名字“REST”——Representational State Transfer(表述性狀態轉移)的縮寫。

  在筆者看來,Fielding這篇博士論文在Web發展史上的價值,不亞于Web之父Tim Berners-Lee關于超文本的那篇經典論文。然而遺憾的是,這篇博士論文在誕生之后的將近5年時間里,一直沒有得到足夠的重視。例如Web Service相關規范SOAP/WSDL的設計者們,顯然不大理解REST是什么,HTTP/1.1究竟是一個什么樣的協議、為何要設計成這個樣子。

  這種情況在2005年之后有了很大的改善,隨著Ajax、Ruby on Rails等新的Web開發技術的興起,在Web開發技術社區掀起了一場重歸Web架構設計本源的運動,REST架構風格得到了越來越多的關注。在2007年1月,支持REST開發的Ruby on Rails 1.2版正式發布,并且將支持REST開發作為Rails未來發展中的優先內容。Ruby on Rails的創始人DHH做了一個名為“World of Resources”的精彩演講,DHH在Web開發技術社區中的強大影響力,使得REST一下子處在Web開發技術舞臺的聚光燈之下。

  今天,各種流行的Web開發框架,幾乎沒有不支持REST開發的了。大多數Web開發者都是通過閱讀某種REST開發框架的文檔,以及通過一些例子代碼來學習REST開發的。然而,通過例子代碼來學習REST有非常大的局限性。因為REST并不是一種具體的技術,也不是一種具體的規范,REST其實是一種內涵非常豐富的架構風格。通過例子代碼來學習REST,除了學習到一種有趣的Web開發技術之外,并不能全面深入的理解REST究竟是什么。甚至還會誤以為這些簡單的例子代碼就是REST本身,REST不過是一種簡單的Web開發技術而已。就像盲人摸象一樣,有的人摸到了象鼻子、有的人摸到了象耳朵、有的人摸到了象腿、有的人摸到了象尾巴。他們都堅信自己感覺到的大象,才是最真實的大象,而其他人的感覺都是錯誤的。

  對于不理解REST的Web開發者,人們習慣于展示一些例子代碼來讓他們理解REST,筆者不贊同上述做法。如果Web開發者想要深入理解REST是什么,就很難避開Fielding的這篇博士論文。筆者在本文中對于REST是什么的介紹,也是基于Fielding的博士論文的。盡管如此,筆者強烈建議本文的讀者親自去通讀一下Fielding的博士論文(論文鏈接),就像想要了解孔子的思想應該直接去讀《論語》等著作,而不是首先去讀其他人的轉述一樣。筆者在本文中也僅僅是努力不做一個把經書念錯了的歪嘴和尚而已。那么,下面我們言歸正傳。

  在Fielding的這篇名為Architectural Styles and the Design of NETwork-based Software Architectures的博士論文(中文版名為《架構風格與基于網絡的軟件架構設計》)中,提出了一整套基于網絡的軟件(即所謂的“分布式應用”)的設計方法,值得所有分布式應用的開發者仔細閱讀、深入體會。

  在論文的前三章中,Fielding在批判性繼承前人研究成果的基礎上,建立起來一整套研究和評價軟件架構的方法論。這套方法論的核心是“架構風格”這個概念。架構風格是一種研究和評價軟件架構設計的方法,它是比架構更加抽象的概念。一種架構風格是由一組相互協作的架構約束來定義的。架構約束是指軟件的運行環境施加在架構設計之上的約束。

  在論文的第四章中,Fielding研究了Web這樣一個分布式系統對于軟件架構設計提出了哪些需求。在第五章中,Fielding將第四章Web提出的需求具體化為一些架構約束,通過逐步添加各種架構約束,推導出來了REST這種新的架構風格。

  REST架構風格的推導過程如下圖所示:

  圖1:REST所繼承的架構風格約束(原圖可在這里下載

  在圖1中,每一個橢圓形里面的縮寫詞代表了一種架構風格,而每一個箭頭邊的單詞代表了一種架構約束。

  REST架構風格最重要的架構約束有6個:

  通信只能由客戶端單方面發起,表現為請求-響應的形式。

  • 無狀態(Stateless)

  通信的會話狀態(Session State)應該全部由客戶端負責維護。

  • 緩存(Cache)

  響應內容可以在通信鏈的某處被緩存,以改善網絡效率。

  • 統一接口(Uniform Interface)

  通信鏈的組件之間通過統一的接口相互通信,以提高交互的可見性。

  • 分層系統(Layered System)

  通過限制組件的行為(即,每個組件只能“看到”與其交互的緊鄰層),將架構分解為若干等級的層。

  • 按需代碼(Code-On-Demand,可選)

  支持通過下載并執行一些代碼(例如Java Applet、Flash或JavaScript),對客戶端的功能進行擴展。

  在論文中推導出的REST架構風格如下圖所示:

  圖2:REST架構風格(原圖可在這里下載

 

  而HTTP/1.1協議作為一種REST架構風格的架構實例,其架構如下圖所示:

  圖3:一個基于REST的架構的過程視圖(原圖可在這里下載

  用戶代理處在三個并行交互(a、b和c)的中間。用戶代理的客戶端連接器緩存無法滿足請求,因此它根據每個資源標識符的屬性和客戶端連接器的配置,將每個請求路由到資源的來源。請求(a)被發送到一個本地代理,代理隨后訪問一個通過DNS查找發現的緩存網關,該網關將這個請求轉發到一個能夠滿足該請求的來源服務器,服務器的內部資源由一個封裝過的對象請求代理(object request broker)架構來定義。請求(b)直接發送到一個來源服務器,它能夠通過自己的緩存來滿足這個請求。請求(c)被發送到一個代理,它能夠直接訪問WAIS(一種與Web架構分離的信息服務),并將WAIS的響應翻譯為一種通用的連接器接口能夠識別的格式。每一個組件只知道與它們自己的客戶端或服務器連接器的交互;整個過程拓撲是我們的視圖的產物。

  通過比較圖2和圖3,讀者不難發現這兩張圖中的架構是高度一致的。對于HTTP/1.1協議為何要設計成這個樣子,讀者想必已經有所領悟。

  在論文的第六章中,Fielding對于到2000年為止在Web基礎架構協議的設計和開發方面的一些經驗教訓進行了深入的分析。其中,“HTTP不是RPC”、“HTTP不是一種傳輸協議”兩部分值得讀者反復閱讀。時至13年之后的今日,對于HTTP協議的誤解仍然廣泛存在。

  以上簡要介紹了Fielding博士論文中的內容。為了幫助讀者仔細閱讀Fielding的博士論文,筆者整理了一套Fielding博士論文的導讀,將在本專欄后續文章中載出。

  REST詳解

  REST究竟是什么?因為REST的內涵非常豐富,所以很難用一兩句話解釋清楚這個問題。

  首先,REST是Web自身的架構風格。REST也是Web之所以取得成功的技術架構方面因素的總結。REST是世界上最成功的分布式應用架構風格(成功案例:Web,還不夠嗎?)。它是為“運行在互聯網環境”的“分布式”“超媒體”系統量身定制的。互聯網環境與企業內網環境有非常大的差別,最主要的差別是兩個方面:

  • 可伸縮性需求無法控制:并發訪問量可能會暴漲,也可能會暴跌。

  • 安全性需求無法控制:無法控制客戶端發來的請求的格式,很可能會是惡意的請求。

  而所謂的“超媒體系統”,即,使用了超文本的系統??梢园?ldquo;超媒體”理解為超文本+媒體內容。

  REST是HTTP/1.1協議等Web規范的設計指導原則,HTTP/1.1協議正是為實現REST風格的架構而設計的。新的Web規范,其設計必須符合REST的要求,否則整個Web的體系架構會因為引入嚴重矛盾而崩潰。這句話不是危言聳聽,做個類比,假如蘇州市政府同意在市區著名園林的附近大型土木,建造大量具有后現代風格的摩天大樓,那么不久之后世界聞名的蘇州園林美景將不復存在。

  上述這些關于“REST是什么”的描述,可以總結為一句話:REST是所有Web應用都應該遵守的架構設計指導原則。當然,REST并不是法律,違反了REST的指導原則,仍然能夠實現應用的功能。但是違反了REST的指導原則,會付出很多代價,特別是對于大流量的網站而言。

  要深入理解REST,需要理解REST的五個關鍵詞:

  1. 資源(Resource)
  2. 資源的表述(Representation)
  3. 狀態轉移(State Transfer)
  4. 統一接口(Uniform Interface)
  5. 超文本驅動(Hypertext Driven)

  什么是資源?

  資源是一種看待服務器的方式,即,將服務器看作是由很多離散的資源組成。每個資源是服務器上一個可命名的抽象概念。因為資源是一個抽象的概念,所以它不僅僅能代表服務器文件系統中的一個文件、數據庫中的一張表等等具體的東西,可以將資源設計的要多抽象有多抽象,只要想象力允許而且客戶端應用開發者能夠理解。與面向對象設計類似,資源是以名詞為核心來組織的,首先關注的是名詞。一個資源可以由一個或多個URI來標識。URI既是資源的名稱,也是資源在Web上的地址。對某個資源感興趣的客戶端應用,可以通過資源的URI與其進行交互。

  什么是資源的表述?

  資源的表述是一段對于資源在某個特定時刻的狀態的描述??梢栽诳蛻舳?服務器端之間轉移(交換)。資源的表述可以有多種格式,例如HTML/XML/JSON/純文本/圖片/視頻/音頻等等。資源的表述格式可以通過協商機制來確定。請求-響應方向的表述通常使用不同的格式。

  什么是狀態轉移?

  狀態轉移(state transfer)與狀態機中的狀態遷移(state transition)的含義是不同的。狀態轉移說的是:在客戶端和服務器端之間轉移(transfer)代表資源狀態的表述。通過轉移和操作資源的表述,來間接實現操作資源的目的。

  什么是統一接口?

  REST要求,必須通過統一的接口來對資源執行各種操作。對于每個資源只能執行一組有限的操作。以HTTP/1.1協議為例,HTTP/1.1協議定義了一個操作資源的統一接口,主要包括以下內容:

  • 7個HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS

  • HTTP頭信息(可自定義)

  • HTTP響應狀態代碼(可自定義)

  • 一套標準的內容協商機制

  • 一套標準的緩存機制

  • 一套標準的客戶端身份認證機制

  REST還要求,對于資源執行的操作,其操作語義必須由HTTP消息體之前的部分完全表達,不能將操作語義封裝在HTTP消息體內部。這樣做是為了提高交互的可見性,以便于通信鏈的中間組件實現緩存、安全審計等等功能。

  什么是超文本驅動?

  “超文本驅動”又名“將超媒體作為應用狀態的引擎”(Hypermedia As The Engine Of Application State,來自Fielding博士論文中的一句話,縮寫為HATEOAS)。將Web應用看作是一個由很多狀態(應用狀態)組成的有限狀態機。資源之間通過超鏈接相互關聯,超鏈接既代表資源之間的關系,也代表可執行的狀態遷移。

  在超媒體之中不僅僅包含數據,還包含了狀態遷移的語義。以超媒體作為引擎,驅動Web應用的狀態遷移。通過超媒體暴露出服務器所提供的資源,服務器提供了哪些資源是在運行時通過解析超媒體發現的,而不是事先定義的。從面向服務的角度看,超媒體定義了服務器所提供服務的協議??蛻舳藨撘蕾嚨氖浅襟w的狀態遷移語義,而不應該對于是否存在某個URI或URI的某種特殊構造方式作出假設。一切都有可能變化,只有超媒體的狀態遷移語義能夠長期保持穩定。

  一旦讀者理解了上述REST的五個關鍵詞,就很容易理解REST風格的架構所具有的6個主要特征:

  • 面向資源(Resource Oriented)

  • 可尋址(Addressability)

  • 連通性(Connectedness)

  • 無狀態(Statelessness)

  • 統一接口(Uniform Interface)

  • 超文本驅動(Hypertext Driven)

  這6個特征是REST架構設計優秀程度的判斷標準。其中,面向資源是REST最明顯的特征,即,REST架構設計是以資源抽象為核心展開的??蓪ぶ氛f的是:每一個資源在Web之上都有自己的地址。連通性說的是:應該盡量避免設計孤立的資源,除了設計資源本身,還需要設計資源之間的關聯關系,并且通過超鏈接將資源關聯起來。無狀態、統一接口是REST的兩種架構約束,超文本驅動是REST的一個關鍵詞,在前面都已經解釋過,就不再贅述了。

  從架構風格的抽象高度來看,常見的分布式應用架構風格有三種:

  • 分布式對象(Distributed Objects,簡稱DO)

  架構實例有CORBA/RMI/EJB/DCOM/.NET Remoting等等。

  • 遠程過程調用(Remote Procedure Call,簡稱RPC)

  架構實例有SOAP/XML-RPC/Hessian/Flash AMF/DWR等等。

  • 表述性狀態轉移(Representational State Transfer,簡稱REST)

  架構實例有HTTP/WebDAV。

  DO和RPC這兩種架構風格在企業應用中非常普遍,而REST則是Web應用的架構風格,它們之間有非常大的差別。

  REST與DO的差別在于:

  • REST支持抽象(即建模)的工具是資源,DO支持抽象的工具是對象。在不同的編程語言中,對象的定義有很大差別,所以DO風格的架構通常都是與某種編程語言綁定的??缯Z言交互即使能實現,實現起來也會非常復雜。而REST中的資源,則完全中立于開發平臺和編程語言,可以使用任何編程語言來實現。

  • DO中沒有統一接口的概念。不同的API,接口設計風格可以完全不同。DO也不支持操作語義對于中間組件的可見性。

  • DO中沒有使用超文本,響應的內容中只包含對象本身。REST使用了超文本,可以實現更大粒度的交互,交互的效率比DO更高。

  • REST支持數據流和管道,DO不支持數據流和管道。

  • DO風格通常會帶來客戶端與服務器端的緊耦合。在三種架構風格之中,DO風格的耦合度是最大的,而REST的風格耦合度是最小的。REST松耦合的源泉來自于統一接口+超文本驅動。

  REST與RPC的差別在于:

  • REST支持抽象的工具是資源,RPC支持抽象的工具是過程。REST風格的架構建模是以名詞為核心的,RPC風格的架構建模是以動詞為核心的。簡單類比一下,REST是面向對象編程,RPC則是面向過程編程。

  • RPC中沒有統一接口的概念。不同的API,接口設計風格可以完全不同。RPC也不支持操作語義對于中間組件的可見性。

  • RPC中沒有使用超文本,響應的內容中只包含消息本身。REST使用了超文本,可以實現更大粒度的交互,交互的效率比RPC更高。

  • REST支持數據流和管道,RPC不支持數據流和管道。

  • 因為使用了平臺中立的消息,RPC風格的耦合度比DO風格要小一些,但是RPC風格也常常會帶來客戶端與服務器端的緊耦合。支持統一接口+超文本驅動的REST風格,可以達到最小的耦合度。

  比較了三種架構風格之間的差別之后,從面向實用的角度來看,REST架構風格可以為Web開發者帶來三方面的利益:

  • 簡單性

  采用REST架構風格,對于開發、測試、運維人員來說,都會更簡單??梢猿浞掷么罅縃TTP服務器端和客戶端開發庫、Web功能測試/性能測試工具、HTTP緩存、HTTP代理服務器、防火墻。這些開發庫和基礎設施早已成為了日常用品,不需要什么火箭科技(例如神奇昂貴的應用服務器、中間件)就能解決大多數可伸縮性方面的問題。

  • 可伸縮性

  充分利用好通信鏈各個位置的HTTP緩存組件,可以帶來更好的可伸縮性。其實很多時候,在Web前端做性能優化,產生的效果不亞于僅僅在服務器端做性能優化,但是HTTP協議層面的緩存常常被一些資深的架構師完全忽略掉。

  • 松耦合

  統一接口+超文本驅動,帶來了最大限度的松耦合。允許服務器端和客戶端程序在很大范圍內,相對獨立地進化。對于設計面向企業內網的API來說,松耦合并不是一個很重要的設計關注點。但是對于設計面向互聯網的API來說,松耦合變成了一個必選項,不僅在設計時應該關注,而且應該放在最優先位置。

  有的讀者可能會問:“你說了這么多,REST難道就沒有任何缺點了嗎?”當然不是,正如Fielding在博士論文中闡述的那樣,評價一種軟件架構的優劣,不能脫離開軟件的具體運行環境。永遠不存在適用于任何運行環境的、包治百病的銀彈式架構。筆者在前面強調過REST是一種為運行在互聯網環境中的Web應用量身定制的架構風格。

  REST在互聯網這個運行環境之中已經占據了統治地位,然而,在企業內網運行環境之中,REST還會面臨DO、RPC的巨大挑戰。特別是一些對實時性要求很高的應用,REST的表現不如DO和RPC。所以需要針對具體的運行環境來具體問題具體分析。但是,REST可以帶來的上述三方面的利益即使在開發企業應用時,仍然是非常有價值的。所以REST在企業應用開發,特別是在SOA架構的開發中,已經得到了越來越大的重視。本專欄將有一篇文章專門介紹REST在企業級應用中與SOA的結合。

  到了這里,“REST究竟是什么”這個問題筆者就解答完了。本文開頭那些說法是否正確,筆者還是笑而不語,讀者此時應該已經有了自己的判斷。在接下來的REST系列文章中,我將會為讀者澄清一些關于HTTP協議和REST的常見誤解。

  參考資料:

  Roy Fielding博士論文英文版

  Roy Fielding博士論文中文版

  HTTP/1.1協議RFC2616RFC2617

  感謝馬國耀對本文的策劃和審校。

it知識庫理解本真的REST架構風格,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 午夜视频在线观看网站 | 国产亚洲精品国产第一 | 五月丁香六月婷综合缴情在线 | 国产福利在线永久视频 | 激情都市亚洲 | 国产91精品久久久久久 | 日韩欧美国产三级 | 久久精品爱国产免费久久 | 91精品国产亚一区二区三区 | 国产在线视频www色 国产在线视频第一页 | 国产99视频精品草莓免视看 | 成人久久网站 | 国产特黄1级毛片 | 国产成人久久精品推最新 | 中文乱码精品一区二区三区 | 四虎4hu永久免费视频大全 | 91免费永久国产在线观看 | 国产高颜值露脸在线观看 | 色视频国产 | 欧美另类极品videosbest视 | 久久精品国产精品亚洲20 | 日韩午夜小视频 | 国产在线观看一区二区三区四区 | 狠狠综合久久综合鬼色 | 一区二区三区四区在线免费观看 | 女人18毛片久久鬼色 | 性夜影院爽黄e爽痛轻点www | 久久精品一区 | 国产激情视频网站 | 好吊妞视频988在线播放 | 91在线综合| 午夜色大片在线观看 | 成人综合婷婷国产精品久久免费 | 日日爱影院 | 中文字幕黄色 | 中文字幕午夜乱理片 | 久久久噜噜噜久久中文字幕色伊伊 | 精品福利视频网 | heyzo国产亚洲高清 | 一本一道dvd在线播放器 | 欧美成人精品欧美一级乱黄 |