亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > .NET > 正文

一個完整的ASP.NET 2.0 URL重寫方案[翻譯]

2024-07-10 13:18:49
字體:
來源:轉載
供稿:網友

這篇文章描述了一個完整的 ASP.NET 2.0 URL 重寫方案。這個方案使用正則表達式來定義重寫規則并解決通過虛擬 URLs 訪問頁面產生回發事件的一些可能的困難。

為什么要重寫 URL ?

將 URL 重寫方法應用到你的 ASP.Net 應用程序的兩個主要原因是:可用性和可維護性。

可用性

誰都知道,相對于難于辨認的帶參數的長的查詢路徑,用戶更喜歡一些短的、簡潔的 URL。任何時候,一個容易記住和敲入的路徑比添加到收藏夾更有用。其次,當一個瀏覽器的收藏夾不可用時,記住的地址總比在搜索引擎中輸入關鍵字進行搜索,然后再查找要強的多。比較下面的兩個地址:

 

(1)

?Year=2006&Month=12&Day=10

(2)

somebloghost.com/Blogs/2006/12/10/

 

第一個 URL 包含了查詢字符串;第二個URL包含的信息可以讓用戶清楚的看到他看的東西,它還可以使用戶更容易的修改地址欄的內容,如:

可維護性

在很多WEB應用程序中,開發人員經常會將頁面從一個目錄移到另一個目錄,讓我們假設一開始有兩個可用頁面:  和 ,但是后來開發者將 Copyright.aspx 和 Contacts.aspx 移到了 Help 目錄,用戶收藏起來地址就需要重新定位。這個問題雖然可以簡單的用 Response.Redirect(new location) 來解決,但是如果有成百上千的頁面呢?應用程序中就會包含大量的無效鏈接。

使用 URL 重寫,允許用戶只需修改配置文件,這種方法可以讓開發者將web應用程序邏輯結構與物理結構獨立開來。

ASP.NET 2.0 中的原有的URL 映射

ASP.NET 2.0 為 web 應用程序提供了一個開箱即用的映射靜態 URL 的解決方案。這個方案不用編寫代碼就可以在 web.config 中將舊的 URLs 映射到新的地址。 要使用 URL 映射,只需在 web.config 文件的 system.web 節中創建一個新的 urlMappings 節 ,并添加要映射的地址 (“ ~/ ”指向應用程序的根目錄):

<urlMappings enabled="true">

   <add url="~/Info/Copyright.aspx" mappedUrl="~/Help/Copyright.aspx" />

   <add url="~/Support/Contacts.aspx" mappedUrl="~/Help/Contacts.aspx" />

</urlMappings>

這樣,如果用戶輸入 , 它將看到 , 而他并不知道那個頁已經移除。

這個方案對于只有兩個頁面被移到其它位置的情況是足夠的。但它對有一打的需要重定位的頁或者需要創建一個整潔的URL來說,它是不合適的。另一個使用Asp.Net 的原有的URL映射技術的不太好的地方是:如果 Contacts.aspx 頁包含的元素在回發到服務器時(這是非??赡艿?, 用戶將會驚奇的發現地址  卻變成了

。  這是因為ASP.NET 引擎用頁面的實際地址修改了表單form 的 action 屬性 ,所以表單就變成了下面的樣子:

<form method="post"
action="http://www.simple-talk.com/Help/Contacts.aspx">

</form>

這樣看來,URL 映射在ASP.NET 2.0 中幾乎是無用的。我們應當能夠使用一個映射規則來指定一系列相似的 URL。最好的解決方案就是使用正則表達式 ( Wikipedia 上可以查看概覽,and 在 .NET 下的實現可以查看 MSDN), 但由于 ASP.NET 2.0 映射不支持正則表達式,所以我們需要開發一個內建到 URL 映射的不同的方案- URL 重寫模塊。 最好的方法就是創建一個可重用的、簡單的配置模塊來實現,顯然我們應創建一個 HTTP 模塊 (關于 HTTP 模塊的詳細信息請查看 MSDN 雜志) 并在獨立的程序集中實現。要使這個程序集簡單易用,我們應實現這個重寫引擎的可配置性,即能夠在 web.config 中指定規則。

 

 

在開發過程中,我們應能使這個重寫模塊打開或關閉 (比如你有一個較難捕獲的bug,而它可能是由不正確的重寫模塊引起的)這樣在 web.config 中對重寫模塊的配置節進行打開或關閉就成為一個選擇。這樣,在 web.config 中,一個配置節的示例如下:

<rewriteModule>

  <rewriteOn>true</rewriteOn>

  <rewriteRules>

      <rule source="(/d+)/(/d+)/(/d+)/"
         destination="Posts.aspx?Year=$1&Month=$2&Day=$3"/>

      <rule source="(.*)/Default.aspx"
         destination="Default.aspx?Folder=$1"/>

  </rewriteRules>

</rewriteModule>

這樣,所有像: 這樣的請示,將會在內部將會用帶參數的請求重定向到 Posts.aspx 。

請注意: web.config 是一個結構良好的 XML 文件, 它禁止在屬性值中使用 & 符號,所以在例子中,應當使用 & 代替。

要在配置文件中使用這個重寫模塊,還需要注冊節和指定處理模塊,像下面這樣增加一個configSections配置節:

 <configSections>

    <sectionGroup>

      <section type="RewriteModule.
RewriteModuleSectionHandler, RewriteModule"/>

    </sectionGroup>

  </configSections>

這樣你就可以在 configSections 節的后面這樣使用了:

<modulesSection>

    <rewriteModule>

      <rewriteOn>true</rewriteOn>

      <rewriteRules>

              <rule source="(/d+)/(/d+)/(/d+)/" destination="Post.aspx?Year=$1&Month=$2&Day=$3"/>

              <rule source="(.*)/Default.aspx" destination="Default.aspx?Folder=$1"/>

      </rewriteRules>

    </rewriteModule>

  </modulesSection>

另一個我們在開發重寫模塊過程中要做的就是還需要允許在虛擬路徑中傳遞參數,象這樣: ?Sort=Desc&SortBy=Date 。所以我們還需要有一個檢測通過虛擬 URL 傳遞參數的解決方案。

 

 

接下來讓我們來創建類庫。首先,我們要引用 System.Web 程序集,這樣我們可以實現一些基于 web 特殊功能。如果要使我們的模塊能夠訪問 web.config,還需要引用 System.Configuration 程序集。

 

處理配置節

要能處理 web.config 中的配置,我們必需創建一個實現了 IConfigurationSectionHandler 接口的類 (詳情查看 MSDN )。如下:

using System;

using System.Collections.Generic;

using System.Text;

using System.Configuration;

using System.Web;

using System.Xml;

 

 

namespace RewriteModule

{

    public class RewriteModuleSectionHandler : IConfigurationSectionHandler

    {

 

        private XmlNode _XmlSection;

        private string _RewriteBase;

        private bool _RewriteOn;

 

        public XmlNode XmlSection

        {

            get { return _XmlSection; }

        }

 

        public string RewriteBase

        {

            get { return _RewriteBase; }

        }

 

        public bool RewriteOn

        {

            get { return _RewriteOn; }

        }

        public object Create(object parent,
                            object configContext,
                            System.Xml.XmlNode section)

        {

            // set base path for rewriting module to

            // application root

            _RewriteBase = HttpContext.Current.Request.ApplicationPath + "http://www.49028c.com/";

 

            // process configuration section

            // from web.config

            try

            {

                _XmlSection = section;

                _RewriteOn = Convert.ToBoolean(
                            section.SelectSingleNode("rewriteOn").InnerText);

            }

            catch (Exception ex)

            {

                throw (new Exception("Error while processing RewriteModule
configuration section.", ex));

            }

            return this;

        }

    }

}

RewriteModuleSectionHandler 類將在 web.config 中的 XmlNode 通過調用 Create 方法初始化。XmlNode 類的 SelectSingleNode 方法被用來返回模塊的配置值。

使用重寫的 URL 的參數

在處理象 http://www. somebloghost.com/Blogs/gaidar/?Sort=Asc (這是一個帶參數的虛擬 URL ) 虛擬的 URLS 時,能夠清楚的辨別通過虛擬路徑傳遞的參數是非常重要的,如下:

<rule source="(.*)/Default.aspx" destination="Default.aspx?Folder=$1"/>,

你可能使用這樣的 URL:

somebloghost.com/gaidar/?Folder=Blogs

它的效果和下面的相似:

somebloghost.com/Blogs/gaidar/

要處理這個問題,我們需要對'虛擬路徑參數' 進行包裝。這可以是通過一個靜態的方法去訪問當前的參數集:

using System;

using System.Collections.Generic;

using System.Text;

using System.Collections.Specialized;

using System.Web;

 

namespace RewriteModule

{

 

    public class RewriteContext

    {

        // returns actual RewriteContext instance for

        // current request

        public static RewriteContext Current

        {

            get

            {

                // Look for RewriteContext instance in

                // current HttpContext. If there is no RewriteContextInfo

                // item then this means that rewrite module is turned off

                if(HttpContext.Current.Items.Contains("RewriteContextInfo"))

                    return (RewriteContext)
HttpContext.Current.Items["RewriteContextInfo"];

                else

                    return new RewriteContext();

            }

        }

 

        public RewriteContext()

        {

            _Params = new NameValueCollection();

            _InitialUrl = String.Empty;

        }

 

        public RewriteContext(NameValueCollection param, string url)

        {

            _InitialUrl = url;

            _Params = new NameValueCollection(param);

           

        }

 

        private NameValueCollection _Params;

 

        public NameValueCollection Params

        {

            get { return _Params; }

            set { _Params = value; }

        }

 

        private string _InitialUrl;

 

        public string InitialUrl

        {

            get { return _InitialUrl; }

            set { _InitialUrl = value; }

        }

    }

}

可以看到,這樣就可以通過RewriteContext.Current 集合來訪問 “虛擬路徑參數”了,所有的參數都被指定成了虛擬路徑或頁面,而不是像查詢字符串那樣了。

重寫 URL

接下來,讓我們嘗試重寫。首先,我們要讀取配置文件中的重寫規則。其次,我們要檢查那些在 URL 中與規則不符的部分,如果有,進行重寫并以適當的頁執行。

創建一個 HttpModule:

class RewriteModule : IHttpModule
{

public void Dispose() { }
public void Init(HttpApplication context)

{}

}

當我們添加 RewriteModule_BeginRequest 方法以處理不符合規則的 URL時,我們要檢查給定的 URL 是否包含參數,然后調用 HttpContext.Current.RewritePath 來進行控制并給出合適的 ASP.NET 頁。

using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

using System.Configuration;

using System.Xml;

using System.Text.RegularExpressions;

using System.Web.UI;

using System.IO;

using System.Collections.Specialized;

 

namespace RewriteModule

{

    class RewriteModule : IHttpModule

    {

 

        public void Dispose() { }

 

        public void Init(HttpApplication context)

        {

            // it is necessary to

            context.BeginRequest += new EventHandler(
                 RewriteModule_BeginRequest);

        }

 

        void RewriteModule_BeginRequest(object sender, EventArgs e)

        {

 

            RewriteModuleSectionHandler cfg =
(RewriteModuleSectionHandler)
ConfigurationManager.GetSection
("modulesSection/rewriteModule");

 

            // module is turned off in web.config

            if (!cfg.RewriteOn) return;

 

            string path = HttpContext.Current.Request.Path;

 

            // there us nothing to process

            if (path.Length == 0) return;

 

            // load rewriting rules from web.config

            // and loop through rules collection until first match

            XmlNode rules = cfg.XmlSection.SelectSingleNode("rewriteRules");

            foreach (XmlNode xml in rules.SelectNodes("rule"))

            {

                try

                {

                    Regex re = new Regex(
                     cfg.RewriteBase + xml.Attributes["source"].InnerText,
                     RegexOptions.IgnoreCase);

                    Match match = re.Match(path);

                    if (match.Success)

                    {

                        path = re.Replace(
                             path,
                             xml.Attributes["destination"].InnerText);

                        if (path.Length != 0)

                        {

                            // check for QueryString parameters

                       if(HttpContext.Current.Request.QueryString.Count != 0)

                       {

                       // if there are Query String papameters

                       // then append them to current path

                       string sign = (path.IndexOf('?') == -1) ? "?" : "&";

                       path = path + sign +
                          HttpContext.Current.Request.QueryString.ToString();

                       }

                       // new path to rewrite to

                       string rew = cfg.RewriteBase + path;

                       // save original path to HttpContext for further use

                       HttpContext.Current.Items.Add(

                         "OriginalUrl",

                         HttpContext.Current.Request.RawUrl);

                       // rewrite

                       HttpContext.Current.RewritePath(rew);

                       }

                       return;

                    }

                }

                catch (Exception ex)

                {

                    throw (new Exception("Incorrect rule.", ex));

                }

            }

            return;

        }

 

    }

}

 

這個方法必須注冊:

public void Init(HttpApplication context)

{

 context.BeginRequest += new EventHandler(RewriteModule_BeginRequest);

}

但這些僅僅完成了一半,因為重寫模塊還要處理表單的回發和虛擬路徑參數集合,而這段代碼中你會發現并沒處理這些。讓我們先把虛擬路徑參數放到一邊,先來正確地處理最主要的回發。

如果我們運行上面的代碼,并通過查看 ASP.NET 的 HTML 源代碼 的 action 會發現,它竟然包含了一個 ASP.NET 的實際路徑頁。例如,我們使用頁 ~/Posts.aspx 來處理像 somebloghost.com/Blogs/2006/12/10/Default.aspx 的請求, 發現 action="/Posts.aspx"。這意味著用戶并沒有使用虛擬路徑進行回發,而是使用了實際的 somebloghost.com/Blog.aspx. 這個并不是我們需要的。所以,需要加一段代碼來處理這些不希望的結果。

首先,我們要在 HttpModule 注冊和實現一個另外的方法:

        public void Init(HttpApplication context)

        {

            // it is necessary to

            context.BeginRequest += new EventHandler(
                 RewriteModule_BeginRequest);

            context.PreRequestHandlerExecute += new EventHandler(
                 RewriteModule_PreRequestHandlerExecute);

        }

 

      void RewriteModule_PreRequestHandlerExecute(object sender, EventArgs e)

        {

            HttpApplication app = (HttpApplication)sender;

            if ((app.Context.CurrentHandler is Page) &&
                 app.Context.CurrentHandler != null)

            {

                Page pg = (Page)app.Context.CurrentHandler;

                pg.PreInit += new EventHandler(Page_PreInit);

            }

        }

這個方法檢查用戶是否請求了一個正常的 ASP.NET 頁,然后為該頁的 PreInit 事件增加處理過程。這兒 RewriteContext 將處理實際參數,然后二次重寫URL。二次重寫是必需的,以使 ASP.NET 能夠在它的表單的action屬性中使用一個虛擬路徑。

void Page_PreInit(object sender, EventArgs e)

        {

            // restore internal path to original

            // this is required to handle postbacks

            if (HttpContext.Current.Items.Contains("OriginalUrl"))

            {

              string path = (string)HttpContext.Current.Items["OriginalUrl"];

 

              // save query string parameters to context

              RewriteContext con = new RewriteContext(
                HttpContext.Current.Request.QueryString, path);

 

              HttpContext.Current.Items["RewriteContextInfo"] =  con;

 

              if (path.IndexOf("?") == -1)

                  path += "?";

              HttpContext.Current.RewritePath(path);

            }

        }

最后,我們來看一下在我們的重寫模塊程序集中的三個類:

 

一個完整的ASP.NET 2.0 URL重寫方案[翻譯]

在 web.config 中注冊重寫模塊

要使用重寫模塊,需要在配置文件中的 httpModules 節注冊重寫模塊,如下:

<httpModules>

<add type="RewriteModule.RewriteModule, RewriteModule"/>

</httpModules>

使用重寫模塊

在使用重寫模塊時,需要注意:

  • 在 web.config 中來使用一些特殊字符是不可能的,因為它是一個結構良好的 XML 文件,因此,你只能用 HTML 編碼的字符代替,如:使用 & 代替 &。
  • 要在你的 ASPX 中使用相對路徑,需要在HTML標簽調用 ResolveUrl 方法,如: <img src="<%=ResolveUrl("~/Images/Test.jpg")%>" />。
  • Bear in mind the greediness of regular expressions and put rewriting rules to web.config in order of their greediness, for instance:
  • <rule source="Directory/(.*)/(.*)/(.*)/(.*).aspx"
    destination="Directory/Item.aspx?
    Source=$1&Year=$2&ValidTill=$3&Sales=$4"/>
    <rule source="Directory/(.*)/(.*)/(.*).aspx"
    destination="Directory/Items.aspx?
    Source=$1&Year=$2&ValidTill=$3"/>
    <rule source="Directory/(.*)/(.*).aspx"
    destination="Directory/SourceYear.aspx?
    Source=$1&Year=$2&"/>
    <rule source="Directory/(.*).aspx"
    destination="Directory/Source.aspx?Source=$1"/>
  • 如果你要在頁面中使用 RewriteModule 而不使用 .aspx,就必須在 IIS 中進行配置以使用期望的擴展映射到請求頁,如下節所述:
  • IIS 配置: 使用帶擴展的重寫模塊代替 .aspx

    要使用帶擴展的重寫模塊代替 .aspx (如 .html or .xml), 必須配置 IIS ,以使這些擴展映射到 ASP.NET 引擎 (ASP.NET ISAPI 擴展)。要進行這些設置,需要以管理員身份登錄。

    打開 IIS 管理控制臺,并選擇你要配置的站點的虛擬路徑:

    Windows XP (IIS 5)
    Virtual Directory "RW"                                

    一個完整的ASP.NET 2.0 URL重寫方案[翻譯]

     

    Windows 2003 Server (IIS 6)
    Default Web Site

    一個完整的ASP.NET 2.0 URL重寫方案[翻譯]

    然后在虛擬路徑標簽上點擊 Configuration… 按鈕  (或如果要使用整個站點都做映射就選擇主目錄標簽)。

    Windows XP (IIS 5)                     

    一個完整的ASP.NET 2.0 URL重寫方案[翻譯]

    Windows 2003 Server (IIS 6)

    一個完整的ASP.NET 2.0 URL重寫方案[翻譯]

    接下來,點擊添加按鈕,并輸入一個擴展,你還需要指定一個 ASP.NET ISAPI 擴展,注意去掉選項的對勾以檢查文件是否存在。

    一個完整的ASP.NET 2.0 URL重寫方案[翻譯]

    如果你要把所有的擴展都映射到 ASP.NET,對Windows XP上的 IIS 5 來說只需要設置 .* 到 ASP.NET ISAPI ,但對 IIS 6 就不一樣了,點擊“添加”然后指定 ASP.NET ISAPI 擴展。

    一個完整的ASP.NET 2.0 URL重寫方案[翻譯]

    總結

    現在,我們已經創建了一個簡單的但非常強大的 ASP.NET 重寫模塊,它支持可基于正則表達式的 URLs 和頁面回發,這個解決方案是容易實現的,并且提供給用戶的例子也是可用的,它可以用簡短的、整潔的URL來替代查詢字符串參數。  要使用這個模塊,只需簡單在你的應用程序中對 RewriteModule 進行引用,然后在 web.config 文件中添加幾行代碼以使你不想顯示的 URL 通過正則表達式代替。這個重寫模塊是很容易部署的,因為只需要在web.config中修改任何“虛擬”的URL即可,如果你需要進行測試,還可以對重寫模塊進行關閉。

    要想對重寫模塊有一個深入的了解,你可以查看本文提供的原代碼。我相信你會發現這是一個比ASP.NET提供的原始映射更好的體驗。

    發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
    色偷偷噜噜噜亚洲男人的天堂| 国产精品激情自拍| 亚洲aaaaaa| 97色在线观看免费视频| 最新日韩中文字幕| 欧美激情视频播放| 欧美一级黑人aaaaaaa做受| 自拍偷拍亚洲区| 亚洲国产成人一区| 日韩美女在线看| 一本大道香蕉久在线播放29| 97精品国产aⅴ7777| 国产精品欧美久久久| 青青草原成人在线视频| 91亚洲国产精品| 一区三区二区视频| 国产小视频91| 在线观看日韩欧美| 国产视频自拍一区| 日韩大片在线观看视频| 国产精品专区h在线观看| 亚洲欧美在线一区二区| 国产欧美日韩精品专区| 日韩免费观看在线观看| 欧美精品videosex牲欧美| 精品久久久久久久久中文字幕| 国产精品999| 亚洲人成网站色ww在线| 欧美另类在线观看| 亚洲黄色www| 亚洲a区在线视频| 欧美日韩加勒比精品一区| 疯狂蹂躏欧美一区二区精品| 高跟丝袜欧美一区| 国产亚洲一级高清| 亚洲成人精品视频在线观看| 亚洲成人精品久久| 国产美女直播视频一区| 国产精品第1页| 成人在线小视频| 日韩一区视频在线| 亚洲大胆人体视频| 91av福利视频| 97人人爽人人喊人人模波多| 国产欧美va欧美va香蕉在线| 国产精品久久久久9999| xxxxx成人.com| 亚洲天堂av在线免费| 亚洲精品免费一区二区三区| 国产午夜精品一区二区三区| www.欧美三级电影.com| 欧美国产精品日韩| 久久久999精品免费| 国产日韩欧美中文| 免费99精品国产自在在线| 中国日韩欧美久久久久久久久| 久久久免费高清电视剧观看| 成人激情在线播放| 91影视免费在线观看| 精品日本高清在线播放| 国产精品永久免费在线| 亚洲精品网站在线播放gif| 国产日产欧美精品| 欧美电影免费在线观看| 亚洲va男人天堂| 97香蕉超级碰碰久久免费软件| 亚洲欧美在线看| 久久男人的天堂| 欧美激情亚洲国产| 中文字幕日韩综合av| 欧美精品在线视频观看| 亚洲成人av在线| 欧美成人午夜免费视在线看片| 日本中文字幕久久看| 日韩欧美精品在线观看| 91精品国产综合久久香蕉最新版| 国产精品丝袜久久久久久高清| 亚洲人成电影网站色…| 精品久久久久久久久久| 亚州成人av在线| 日韩欧美国产骚| 亚洲精品美女久久| 欧美国产精品va在线观看| 亚洲字幕在线观看| 日韩欧美aaa| 欧美二区在线播放| 成人伊人精品色xxxx视频| 亚洲成色777777在线观看影院| 91午夜理伦私人影院| 久久精品国产电影| 欧美精品在线免费观看| 91精品久久久久久综合乱菊| 色噜噜狠狠狠综合曰曰曰| 91亚洲精品久久久久久久久久久久| 深夜成人在线观看| 中文字幕亚洲专区| 亚洲精品自拍视频| 欧美国产视频一区二区| 亚洲精品一区二三区不卡| 亚洲sss综合天堂久久| 欧美怡春院一区二区三区| 91精品视频专区| 成人午夜激情网| 亚洲国产欧美一区二区丝袜黑人| 国产一区二区三区18| 亚洲国产天堂久久综合| 久久久久中文字幕2018| 久久69精品久久久久久久电影好| 欧美激情xxxxx| 久久精品久久久久| 久久久久久久久久久久久久久久久久av| 日韩视频免费大全中文字幕| 日韩欧美国产激情| 日本精品va在线观看| 精品无码久久久久久国产| 久久精品久久久久久国产 免费| 全色精品综合影院| 久久国内精品一国内精品| 亚洲第一男人天堂| 久久91精品国产91久久跳| 亚洲精品大尺度| 九九久久国产精品| 欧美日韩午夜视频在线观看| 日韩理论片久久| 国产视频久久网| 欧美国产精品日韩| 欧美大肥婆大肥bbbbb| 亚洲男女性事视频| 国产91色在线免费| 久久全球大尺度高清视频| 欧美在线视频一区二区| 日韩av电影手机在线| 国产成人短视频| 日本精品一区二区三区在线播放视频| xvideos国产精品| 久久亚洲精品成人| 久久国产精品久久国产精品| 日本久久久久亚洲中字幕| 国产精品爽黄69天堂a| 国产成人精品久久二区二区91| 草民午夜欧美限制a级福利片| 国产精品视频精品视频| 亚洲成人久久久| 91高清视频在线免费观看| 热99久久精品| 欧美性在线观看| 国模极品一区二区三区| 国产精品美腿一区在线看| 亚洲成人黄色在线| 欧美怡春院一区二区三区| 欧美日韩xxxxx| 中文字幕国产亚洲2019| 久久91亚洲精品中文字幕| 亚洲第一精品久久忘忧草社区| 精品国产电影一区| 久99九色视频在线观看| 午夜精品久久久久久久99热浪潮| 国产福利成人在线| 国产精品va在线播放我和闺蜜| 永久555www成人免费| 亚洲最大成人网色| 成人免费淫片aa视频免费| 97久久精品人搡人人玩| 亚洲福利视频网站|