近期做网站,想试着进行URL重写,隐藏部分关键要素,但是找了一些文档,大多是配置web.config,而且还需要第三方插件,后来研究一番,其实很简单,只需要了解asp.net的运行机制和正则表达式即可。
通常我们在浏览器中输入一个url,当返回结果时地址栏的url改变了.例如cnblogs,输入http://test.cnblogs.com,结果反馈回来后地址为http://www.cnblogs.com/test,在其他的站点我们同样可以见到这种应用,尤其是一些提供blog服务和bbs站点.当输入http://site.com/2004给出2004年所有的文章,输入http://site.com/2004/5会给出2004年5月份的所有文章(在此site只为举例方便,不一定会有这个站点).这就是url重写的应用.这种好处:
- 易于键入;
- 能够使人很好的理解站点的结构;
- 允许用户通过删除 URL 的组成部分来浏览站点;
- 除此之外,还方便站点重组.以免导致链接失效或书签过期.
首先看看iis对请求的处理.当请求传入iis服务器时,iis将会检查拓展名以决定如何进行处理.iis自行处理静态的内容,如html,图像等其他静态内容.对于动态内容,iis会将请求路由到ISAPI扩展,由对应的处理引擎或程序进行处理,最后将处理的结果以静态html形式交给iis,iis返回最终的响应.
不仅如此,IIS 将尝试对发出请求的用户进行身份验证,并确定通过身份验证的用户是否有权限访问被请求的文件。在处理请求的有效期内,IIS 将经历几个状态。在每个状态下,IIS 都将引发可以使用 ISAPI 筛选器以编程方式进行处理的事件.与 ISAPI 扩展一样,ISAPI 筛选器是在Web服务器上安装的非托管代码块.ISAPI扩展被设计为可以响应针对特定文件类型的请求.另外,ISAPI筛选器还包含可以对IIS引发的事件进行响应的代码.ISAPI筛选器可以截取甚至修改传入和传出的数据
而asp.net引擎可以在处理请求时触发事件,允许任意数量的http模块处理引发的事件,这与iis的ISAPI筛选器相似。在asp.net引擎首次响应请求时,BeginRequest 事件将被触发,接下来触发的是AuthenticateRequest 事件(该事件在已建立用户标识时出现),还会有其他大量的事件,因此,只需要在这些事件中进行处理即可。
实例:我们将…./user/abc123 这样的链接经过URL重写,交给url.aspx?uid=abc123这样的页面进行处理。
一、在项目中创建全局处理文件Global.asax
二、对事件protected void Application_BeginRequest(object sender, EventArgs e)进行事件响应处理,主要思路是获取请求的URL,通过正则表达式匹配,提取关键数据,再交由处理页面处理。
参考代码如下:
url.aspx 页面建立一个Label控件,ID为Label1
protectedvoid Page_Load(objectsender, EventArgs e)
{
if(Request.QueryString["uid"] != null)
Label1.Text = Request.QueryString["uid"].ToString();
else
Label1.Text = "nouid";
}
Global.asax中的事件处理代码:
protectedvoid Application_BeginRequest(objectsender, EventArgs e)
{
ReWriteUrl("user","url.aspx","uid");
}
/// <summary>
/// Url重写,将/url/[key]形式的链接映射到/page?parameter=key进行处理
/// </summary>
/// <param name="url">url路径</param>
/// <param name="page">处理页面</param>
/// <param name="parameter">url路径下的参数</param>
privatevoid ReWriteUrl(stringurl,stringpage,stringparameter)
{
stringpat = "(.*)/"+ url + "/[a-zA-Z0-9]+";
Regex oReg = newRegex(pat);
Match m = oReg.Match(Request.Url.ToString());
stringkey;
if(m.Success)
{
key = m.Groups[0].Value;
key = key.Substring(key.LastIndexOf('/') + 1, key.Length - key.LastIndexOf('/') - 1);
}
else
{
return;
}
stringnewString = string.Format("/{0}?{1}={2}", page, parameter, key);
stringReWriteUrl = oReg.Replace(Request.Url.ToString(), newString);
HttpContext.Current.RewritePath(ReWriteUrl);
}