<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java Votary

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      48 隨筆 :: 1 文章 :: 80 評論 :: 0 Trackbacks

    在Java2平臺企業(yè)版中應用異步JavaScript技術(shù)和XML(AJAX)

    在Java2平臺企業(yè)版中應用異步JavaScript技術(shù)和XML(AJAX)
    作者 Greg Murray, 2005年6月9日June 9, 2005 翻譯: ShiningRay @ Nirvana Studio 2005年9月9日
    任何試過過Flickr、GMail、Google Suggest或者是Google Maps的人都會意識到一種新型的動態(tài)Web應用正在逐漸浮出水面。這些應用外觀和表現(xiàn)都和傳統(tǒng)的桌面應用程序很像,而他們不需要依賴于插件或者是特定于 瀏覽器的功能。過去Web應用只是一系列HTML頁面,他們?nèi)我庖徊糠輧?nèi)容的更改都必須重新載入頁面。像JavaScript編程語言和層疊樣式表 (CSS)之類的技術(shù)已經(jīng)成熟,可以有效地應用他們來創(chuàng)建高動態(tài)的Web應用,而且可以運行在所有的主流瀏覽器中。本文將會詳細介紹你馬上就可以使用的一 些技術(shù),讓他們使你的Web應用像桌面應用更加豐富和更有交互性。


    介紹異步JavaScript技術(shù)和XML(AJAX)

    使用JavaScript技術(shù),一個HTML頁面可以異步地對服務器(一般是載入頁面的服務器)發(fā)送請求并獲取XML文檔。然后JavaScript可以 使用XML文檔來更新或改動HTML頁面的文檔對象模型(DOM)。最近形成了一個術(shù)語 AJAX (Asynchronous JavaScript Technology and XML)來描述這種交互模型。

    AJAX其實不是很新的東西。這些技術(shù)對于Windows平臺上專注于Internet Explorer的開發(fā)人員來說,已經(jīng)存在好幾年了。直到最近,這個技術(shù)才被作為Web遠程技術(shù)或者遠程腳本技術(shù)被大家了解。Web開發(fā)人員也有一段時間曾經(jīng)使用過插件、Java applet和隱藏框架來模擬這種交互模型。最近發(fā)生的變化是,對 XMLHttpRequest 對象的支持已經(jīng)成為所有平臺上的主流瀏覽器都包括的特性了。JavaScript技術(shù)的 XMLHttpRequest 對象是。盡管在正式的JavaScript技術(shù)標準中并沒有提到這種對象,然而今天主流的瀏覽器都對他提供了支持。而當代的瀏覽器如Firefox、Internet Explorer以及Safari在JavaScript技術(shù)和CSS的支持上有些細微的差別,但是這種差別是可以處理的。如果你要考慮支持較老的瀏覽器,AJAX也許就不能成為你的解決方法。

    基于AJAX的客戶端之所以獨特的原因是客戶端包含了用JavaScript嵌入的特定于頁面的控制邏輯。應用JavaScript技術(shù)的頁面基于 事件進行交互,如文檔載入、鼠標點擊、焦點改變甚至是定時器。AJAX交互使得表現(xiàn)層邏輯更加清晰地與數(shù)據(jù)分離。一個HTML頁面也可以根據(jù)需要每次讀入 適當?shù)臄?shù)據(jù),而不是每次需要顯示一個更改時都重新載入整個頁面。AJAX要求一種不同的服務器架構(gòu)來支持它這種交互模型。以前,服務器端Web應用關(guān)注于 對每個導致服務器調(diào)用的客戶端事件都生成HTML文檔。然后客戶端對每個回應都要重新讀入并重新渲染完整的HTML頁面。富Web應用(Rich Web Application)關(guān)注于,讓一個客戶端獲取一個HTML文檔讓它表現(xiàn)為一個模板或者是一個容器,可以基于事件并使用從服務器端組件中獲取的XML 數(shù)據(jù)來對文檔注入內(nèi)容。

    一些AJAX交互的應用如:

    • 實時表單數(shù)據(jù)檢驗: 像用戶ID、序列號、郵政編碼或者是特殊的票據(jù)代碼這類需要服務器端驗證的數(shù)據(jù)也可以在用戶提交表單之前進行驗證。
    • 自動補全: 像電子郵件地址、姓名或城市名之類的表單數(shù)據(jù)都可以根據(jù)用戶情況自動補全。
    • 處理細節(jié)操作: 根據(jù)一個客戶端事件,一個HTML頁面可以根據(jù)現(xiàn)存的一些數(shù)據(jù)再去獲取更多詳細的信息,如現(xiàn)在有一個產(chǎn)品列表,客戶端可以控制查看單獨的產(chǎn)品信息而無需刷新頁面。
    • 復雜的用戶界面控件: 像樹型控件、菜單和進度條之類不要求頁面刷新的控件也能實現(xiàn)。
    • 頁面內(nèi)刷新數(shù)據(jù): HTML頁面可以從服務器上查詢最新的數(shù)據(jù)如分數(shù)、股指、天氣還有其它的特定于應用的數(shù)據(jù)。
    • 服務器端通知: 一個HTML頁面可以通過對服務器進行定時查詢來模擬一個服務器的事件通知推送,實現(xiàn)像通知客戶端一個消息、刷新頁面數(shù)據(jù)或?qū)⒖蛻舳酥囟ㄏ虻搅硪粋€頁面。

    這個列表并未把所有的應用都列出來,但它已經(jīng)顯示了AJAX交互可以讓Web應用比從前能做更多的事情。但盡管這些好處是值得關(guān)注的,這種方式也有 一些缺點:

    • 復雜度: 服務器端開發(fā)人員必需理解,HTML客戶端頁面中的表現(xiàn)層邏輯以及生成HTML客戶端頁面所需的XML內(nèi)容的服務器端邏輯。HTML頁面開發(fā)人員必須了解 JavaScript技術(shù)。如果開發(fā)新的框架和發(fā)展已有的框架來支持這種交互模型,那么AJAX應用的創(chuàng)建就會越來越簡單。
    • XMLHttpRequest 對象的標準化: XMLHttpRequest 對象還不是JavaScript技術(shù)標準的一部分,這就意味著根據(jù)客戶端的不同,應用的行為也有所會不同。
    • JavaScript技術(shù)的實現(xiàn): AJAX交互極大地依賴于JavaScript技術(shù),而由于客戶端的原因JavaScript還有一些細微的差別。見 QuirksMode.org 來了解更多關(guān)于瀏覽器之間區(qū)別的內(nèi)容。
    • 調(diào)試: AJAX應用也難于調(diào)試,因為流程邏輯是同時嵌在客戶端中和服務器上的。
    • 代碼可見: 客戶端的JavaScript可以很容易通過“查看源代碼”被人看見。一個沒有良好設(shè)計的AJAX應用很可能被黑客攻擊或被他人剽竊。

    當開發(fā)人員在使用AJAX交互模型上獲得更多的經(jīng)驗后,AJAX技術(shù)的框架和模式就會慢慢浮現(xiàn)出來。現(xiàn)在就關(guān)注于完全通用的AJAX交互框架,還為 時過早。本文和相關(guān)的解決方案將關(guān)注于在現(xiàn)有的Java 2平臺企業(yè)版(J2EE)上如何對AJAX進行支持,像servlet,JavaServer Page(JSP)軟件、JavaServer Face應用和Java標準標簽庫(JSTL)。


    AJAX交互剖析

    現(xiàn)在我們已經(jīng)討論了AJAX是什么以及一些高層次的問題。那現(xiàn)在讓我們把所有的零件放在一起來展示一個具有AJAX的J2EE應用。

    首先考慮一個例子。一個Web應用包括了一個靜態(tài)HTML頁面,或者是一個由 JSP 生成的HTML頁面,這個JSP中還包括了一個HTML表單,它需要服務器端邏輯來對表單中的數(shù)據(jù)進行檢驗,而不用刷新頁面。一個名為 ValidateServlet 服務器端組件( servlet )用來提供這種驗證邏輯。圖一描述了這種具有驗證邏輯的AJAX交互的細節(jié)。

    AJAX Interaction
    圖1: 一個提供驗證邏輯的AJAX交互

    以下條目代表了圖1中出來AJAX交互的過程:

    1. 發(fā)生一個 客戶端事件
    2. 創(chuàng)建和配置一個 XMLHttpRequest 對象。
    3. XMLHttpRequest 對象進行一個調(diào)用。
    4. ValidateServlet 對請求進行處理。
    5. ValidateServlet 返回一個包含了結(jié)果的XML文檔。
    6. XMLHttpRequest 對象調(diào)用 callback() 函數(shù)并處理結(jié)果。
    7. 更新 HTML DOM。
    現(xiàn)在讓我們逐個研究這個AJAX模型的每一步。

    1. 發(fā)生一個客戶端事件。

    在一個事件發(fā)生時可以調(diào)用相應的JavaScript函數(shù)。在這里, validate() 函數(shù)可以被映射到一個鏈接或者是表單組件的 onkeyup 事件上去。


    size="20"
    id="userid"
    name="id"
    script_onkeyup="validate();">

    每次用戶在表單域中按下一個鍵時,表單元素將都調(diào)用 validate() 函數(shù)。

    2. 建立和配置一個 XMLHttpRequest 對象

    創(chuàng)建和配置一個 XMLHttpRequest 對象

    var req;

    function validate() {
    var idField = document.getElementById("idField");
    var url = "validate?id=" + escape(idField.value);
    if (window.XMLHttpRequest) {
    req = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
    req = new ActiveXObject("Microsoft.XMLHTTP");
    }
    req.open("GET", url, true);
    req.onreadystatechange = callback;
    req.send(null);
    }

    validate() 函數(shù)建立了一個 XMLHttpRequest 對象并對象中的open函數(shù)。open函數(shù)需要兩個參數(shù):HTTP方法,可以是 GET POST ; 和對象進行交互的服務器端組件的URL;一個布爾變量,表示是否要進行異步調(diào)用。API是 XMLHttpRequest.open(String method, String URL, boolean asynchronous) 。如果一個交互被設(shè)置為異步, ( true ) 那就必須指明一個回調(diào)函數(shù)。可以使用 req.onreadystatechange = callback; 來設(shè)置這個交互的回調(diào)函數(shù)。詳細內(nèi)容見第六節(jié)。

    3. XMLHttpRequest 對象進行調(diào)用

    當收到了語句 req.send(null); ,就會進行一次調(diào)用。HTTP GET 的情況下,內(nèi)容可以是 null 或者留空。當調(diào)用 XMLHttpRequest 的這個函數(shù)時,也會對已經(jīng)配置了的URL進行調(diào)用。在下面這個例子中,要發(fā)送的數(shù)據(jù)( id )將作為一個URL參數(shù)。

    使用HTTP GET ,兩個重復的請求將返回同樣的結(jié)果。當使用HTTP GET 方法時,要注意URL的長度,包括已經(jīng)轉(zhuǎn)義的URL參數(shù),可能會受到某些瀏覽器和服務器端的Web容器的限制。當發(fā)送的數(shù)據(jù)會影響到服務器端的應用程序的狀態(tài)時,就應該使用HTTP POST 方法。使用HTTP POST 必須要對 XMLHttpRequest 對象設(shè)置一個 Content-Type 頭,使用以下語句:

    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send("id=" + escape(idTextField.value));

    當從JavaScript中發(fā)送表單值得時候,你應該考慮對字段值進行編碼。JavaScript中有一個函數(shù) escape() ,應該用他來確保區(qū)域化的內(nèi)容被正確編碼,同時特殊字符也被正確轉(zhuǎn)義。

    4. ValidateServlet 對請求進行處理.

    一個映射到URI "validate" 的servlet將檢驗user ID是不是已經(jīng)在數(shù)據(jù)庫中存在了。

    一個servlet處理一個 XMLHttpRequest ,就像對待其它的HTTP請求一樣。 下面的例子顯示了服務器從請求中抽取出 id 參數(shù)并檢驗是否被占用了。

    public class ValidateServlet extends HttpServlet {

    private ServletContext context;
    private HashMap users = new HashMap();

    public void init(ServletConfig config) throws ServletException {
    this.context = config.getServletContext();
    users.put("greg","account data");
    users.put("duke","account data");
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {

    String targetId = request.getParameter("id");

    if ((targetId != null) && !users.containsKey(targetId.trim())) {
    response.setContentType("text/xml");
    response.setHeader("Cache-Control", "no-cache");
    response.getWriter().write("valid");
    } else {
    response.setContentType("text/xml");
    response.setHeader("Cache-Control", "no-cache");
    response.getWriter().write("invalid");
    }
    }
    }

    在這個例子中,一個簡單的HashMap用來存放存在的用戶名。在這個例子中,我們假設(shè)用戶的ID是 duke

    5. ValidateServlet 返回一個包含結(jié)果的XML文檔

    用戶ID "duke" 在 users HashMap 的用戶ID列表中出現(xiàn)了。將在應答中寫一個包含值為 invalid message 元素的XML文檔。更復雜的用例將要求DOM、XSLT或其他API來生成這個應答。

        response.setContentType("text/xml");
    response.setHeader("Cache-Control", "no-cache");
    response.getWriter().write("invalid");

    開發(fā)人員必須注意兩個事情。第一, Content-Type 必須設(shè)為 text/xml 。第二, Cache-Control 必須設(shè)為 no-cache XMLHttpRequest o對象只會處理 Content-Type text/xml 的應答,同時把將 Cache-Control 設(shè)為 no-cache 將確保瀏覽器不會從緩存相同的URL(包括參數(shù))返回的應答。

    6. XMLHttpRequest 對象調(diào)用 callback() 函數(shù)并處理結(jié)果。

    The XMLHttpRequest 對象已經(jīng)配置為當有 readyState 改變的時候就調(diào)用 callback() 函數(shù) 。讓我們假設(shè)已經(jīng) ValidateServlet 調(diào)用了而且 ValidateServlet 4 ,表示 XMLHttpRequest 的調(diào)用已經(jīng)完成。HTTP狀態(tài)代碼 200 表示一個成功的HTTP交互。

    function callback() {
    if (req.readyState == 4) {
    if (req.status == 200) {
    // update the HTML DOM based on whether or not message is valid
    }
    }
    }

    瀏覽器維護了一個所顯示的文檔的對象形式(也就是所謂的Docuemt Object Model或DOM)。HTML頁面中的JavaScript可以訪問DOM,同時在頁面載入完之后,可以使用API來修改DOM。

    根據(jù)成功的請求,JavaScript代碼可以修改HTML頁面的DOM。從 ValidateServlet 獲得的對象形式的XML文檔可以通過 req.responseXML 在JavaScript中獲得, req 是一個 XMLHttpRequest 對象。DOM API給JavaScript提供了獲取這個文檔中的內(nèi)容以及修改HTML頁面的DOM的方法。所返回的字符串形式的XML文檔可以通過 req.responseText 獲得。現(xiàn)在我們看看如何在JavaScript中使用DOM API,先看以下從 ValidateServlet 返回的XML文檔。

     
    valid


    這個例子是一個簡單的只包含了一個 message 元素的XML片斷,里面只有一個簡單的字符串 valid invalid 。一個更高級的例子可以包含多于一個的消息和可以給用戶看的有效的名字:

    function parseMessage() {
    var message = req.responseXML.getElementsByTagName("message")[0];
    setMessage(message.childNodes[0].nodeValue);
    }

    parseMessages() 函數(shù)將處理一個從 ValidateServlet 獲取的XML文檔。這個函數(shù)會調(diào)用 setMessage() with the,并給出 message 作為參數(shù)來更新HTML DOM。

    7. 更新了HTML DOM

    JavaScript技術(shù)可以使用很多API從HTML DOM中獲得任何元素對象的引用。推薦的獲得元素引用的方法是調(diào)用 document.getElementById("userIdMessage") , "userIdMessage" 是HTML文檔中出現(xiàn)的一個元素的ID屬性。有了這個元素的引用,就可以使用JavaScript來修改元素的屬性、修改元素的樣式、添加、刪除或修改子元素。

    一個常見的改變元素主體內(nèi)容的方法是設(shè)置元素的 innerHTML 屬性,如下所示:

    <script>
    function setMessage(message) {
    var userMessageElement = document.getElementById("userIdMessage");
    userMessageElement.innerHTML = "" + message + " ";
    }
    </script>




    受到影響的那部分HTML頁面會立刻根據(jù) innerHTML 的設(shè)置重新渲染。如果 innerHTML 屬性包含類似 或者是 之類的元素,那么由那些元素所指定的內(nèi)容同樣會被獲取并渲染。

    這種途徑的主要缺點是HTML元素是作為字符串硬編碼在JavaScript中的。JavaScript中硬編碼的HTML標記不是一種好的實踐,因為它 使代碼難于閱讀、維護和修改。我們應該考慮在JavaScript中使用DOM API來創(chuàng)建和修改HTML元素。把顯示和JavaScript代碼的字符串混在一起只會讓頁面更難于閱讀和編輯。

    另一種修改HTML DOM的方法是動態(tài)地產(chǎn)生新的元素并把他們作為子元素追加到目標元素,如下面的例子所示:

    <script>
    function setMessage(message) {
    var userMessageElement = document.getElementById("userIdMessage");
    var userIdMessageFont = document.getElementById("userIdMessageFont");
    var messageElement = document.createTextNode(message);
    if (userMessageElement.childNodes[0]) {
    // 更新元素
    userIdMessageFont.replaceChild(messageElement, userIdMessageFont.childNodes[0]);
    } else {
    // 建立一個新的元素
    var fontElement = document.createTextNode("font");
    fontElement.setAtribute("id", "userIdMessageFont");
    fontElement.setAtribute("color", "red");
    userMessageElement.appendChild(fontElement);
    fontElement.appendChild(messageElement);
    }
    }
    </script>




    這個范例展示了JavaScript技術(shù)的DOM API可以用來更有目的地建立或改變一個元素。當然JavaScript的DOM AP在不同的瀏覽器上也可能有差別,所以你必須在開發(fā)應用程序時小心。


    Java BluePrint的解決方案目錄

    The Java Blueprints Solutions Catalog 是用來收集J2EE技術(shù)上AJAX的最佳實踐的。每個解決方案包含一個問題和方法的描述、一個設(shè)計文檔和可運行的源碼。這些解決方案是為了讓你根據(jù)需要在自己的應用程序中復用。以下是已經(jīng)提供的AJAX交互:

    自動補全

    自動補全 提供了當用戶在一個HTML表單中輸入一個請求時對數(shù)據(jù)瀏覽的簡化方式。當用戶面對一大片數(shù)據(jù)時,可以在輸入數(shù)據(jù)時把可能的完整形式顯示給用戶。然后選擇 其中一個完整形式可以保證用戶輸入的數(shù)據(jù)已經(jīng)存在在服務器上。

    考慮一個大公司的一個名字查找的Web應用。如圖2所示,只要輸入姓或名的開頭幾個字母就可以得到人的列表。用戶可以然后就只要點擊一下就可以瀏覽用戶的詳細信息。

    Autocompletion of a Name
    圖2:名字自動補全
    進度條

    在Web 應用中,一個服務器端任務也可能要花一段時間去完成。這段時間很可能會超過HTTP交互的時間上限(超時)。當用戶不知道這個任務什么時候才能完成時,用 戶很可能會重新提交一次表單或直接退出會話狀態(tài)。一般來說,Web應用使用頁面刷新來跟蹤服務器端操作的狀態(tài),這種方式可能會讓人厭煩而且也不準確。 AJAX可以用來僅在一個HTML頁面中跟蹤服務器端操作的狀態(tài)而無需刷新頁面。用戶可以以圖形方式看到服務器端操作的進度,如圖3。

    Progress Bar
    圖3: 進度條
    刷新數(shù)據(jù)

    向 一個HTML頁面提供最新的數(shù)據(jù)或服務器消息提醒在現(xiàn)在的Web世界中也是十分重要的,因為現(xiàn)在的Web世界中數(shù)據(jù)一直不停變化。盡管它不是一個實實在在 的推送技術(shù),但它可以通過使用AJAX交互不斷進行查詢來模擬。當數(shù)據(jù)需要更新或者要進行提醒,HTML頁面將會動態(tài)地改變。圖4顯示了HTML頁面中的 一個服務器端計數(shù)器。這個計數(shù)器會在頁面后臺自動更新。

    Server-side Counter Shows Refreshing Data
    圖4:服務器端計數(shù)器在刷新數(shù)據(jù)
    實時檢驗

    不是所有的表單域都可以單獨用JavaScript技術(shù)在客戶端完成。某些表單數(shù)據(jù)要求服務器端的驗證邏輯。傳統(tǒng)和Web應用曾使用頁面刷新來完成 這種驗證,但這可能有些讓人煩。

    考慮一個需要一個唯一用戶ID的Web應用。使用AJAX交互,用戶可以在輸入的時候就知道ID是否有效(圖5)。

    Invalidating the ID as User Types
    圖5:指出用戶ID無效

    當一個用戶輸入了一個無效的用戶ID,應用程序禁止了提交按鈕并且向用戶顯示了一個信息(圖6)。

    Validating the ID as User Types
    圖6:用戶ID通過驗證

    用戶馬上就能知道用戶ID是可用的也是有效的。


    最后的思考

    我們已經(jīng)看到AJAX交互可以解決很多問題。配合HTTP處理、數(shù)據(jù)庫、Web服務、XML處理和業(yè)務對象等API,J2EE技術(shù)已經(jīng)提供了一個開 發(fā)和部屬基于AJAX應用的一個良好的基礎(chǔ)。有了對于這個交互模型的更好的理解,今天的應用程序可以變得更加有交互性,給最終用戶更好的體驗。

    使用AJAX要求你使用支持 XMLHttpRequest 對象的最新瀏覽器版本。使用AJAX還要求大量對JavaScript技術(shù)和CSS的應用。作為一個應用程序架構(gòu)師或是一個開發(fā)人員,你要會針對瀏 覽器支持、架構(gòu)復雜度和對開發(fā)人員的培訓等方面來衡量開發(fā)一個富應用的需要。當AJAX編程模型不斷地發(fā)展,現(xiàn)有的技術(shù)和框架會讓這種轉(zhuǎn)變更加容易。

    很明顯的是,突出的Web應用都越來越有交互性了。那么你的呢?


    更多信息

    關(guān)于作者

    Greg Murray 是 Sun Microsystems 的一名工程師,是servlet標準的領(lǐng)導人,BluePrint小組的前成員,在這個小組時他已經(jīng)開始關(guān)注Web層次問題。他也是《 Enterprise Applications With the Java 2 Platform,Enterprise Edition and Designing Web Services With the J2EE 1.4 Platform (Addison-Wesley)》一書的協(xié)助編撰者。


    引用

    http://www2.uuzone.com/app/trackBack.do?type=blog&trackBackID=39739
    posted on 2005-11-23 11:43 Dion 閱讀(1925) 評論(4)  編輯  收藏 所屬分類: Ajax

    評論

    # re: 在Java2平臺企業(yè)版中應用異步JavaScript技術(shù)和XML(AJAX) 2005-12-16 21:13 jess
    那里有源代碼,說的好聽。  回復  更多評論
      

    # re: 在Java2平臺企業(yè)版中應用異步JavaScript技術(shù)和XML(AJAX) 2005-12-16 21:14 jess
    什么時間把你上面抓圖的源碼我看看。  回復  更多評論
      

    # re: 在Java2平臺企業(yè)版中應用異步JavaScript技術(shù)和XML(AJAX) 2006-03-09 10:16 guoguo1
    我以前做過一個ajax的應用,步驟確實如樓主所寫的,除了返回的值是一個xml字符串之外幾乎完全相同。

    后面那么什么都不懂的人不懂就不要瞎評論!!!  回復  更多評論
      

    # re: 在Java2平臺企業(yè)版中應用異步JavaScript技術(shù)和XML(AJAX) 2006-06-27 11:40 leko
    以前用過,挺實用的.現(xiàn)在才知道是AJAX  回復  更多評論
      

    主站蜘蛛池模板: 亚洲精品午夜无码专区| 亚洲人成片在线观看| 精品无码AV无码免费专区| 亚洲AV男人的天堂在线观看| 亚洲无av在线中文字幕| 95老司机免费福利| 亚洲国产精品自在自线观看| 国产AV无码专区亚洲AV手机麻豆| 亚洲无砖砖区免费| 黄色三级三级免费看| 久久精品蜜芽亚洲国产AV| 国产免费无遮挡精品视频| 亚洲一级特黄特黄的大片| 亚洲伊人成无码综合网 | 无码人妻精品中文字幕免费东京热| 亚洲人成人网站18禁| 亚洲AV无码一区二区乱子伦 | 亚洲中文字幕无码一区二区三区| 四虎最新永久免费视频| 精品国产污污免费网站入口| 亚洲一区电影在线观看| 亚洲日韩国产精品第一页一区| 成年男女男精品免费视频网站| 怡红院免费的全部视频| 亚洲免费网站观看视频| 久久精品国产亚洲av麻豆小说| www国产亚洲精品久久久日本| 亚州免费一级毛片| 国色精品va在线观看免费视频| 久久久亚洲精华液精华液精华液| 中文字幕亚洲综合久久2| 久久亚洲中文字幕精品一区| 在线免费观看一区二区三区| 99在线观看免费视频| ssswww日本免费网站片| 性色av极品无码专区亚洲| 亚洲成人黄色在线| 亚洲国产精品lv| 国产亚洲一区二区三区在线观看| 免费一级e一片在线播放| 成人免费在线观看网站|