【伪】另类方法实现URL重写
2010-09-10 00:00 Feather 阅读(195) 评论(0) 收藏 举报关于URL重写的讨论很多,方法也很多,主要也无异于两种,一个是通过配置服务器,一个是通过配置ASP.Net的IHttpModule等底层设置。实现这些功能的组件网上也不少,ASP.Net MVC框架里面也有一个独立于该框架的URL重写组件,里面具体怎么实现,我也不太清楚,毕竟我也只是弱弱地玩了一下而已。
可能很多人看这我这个url就看出来是怎么实现的,如果你就是这些大牛,又或者你觉得我的url不够帅,请跳过。
帅!伪!
嗯,本文的主旨有两个:帅和伪。就是用最伪的方法尽可能地让URL更帅,本着这个原则,我们开始吧。
为了突出我们本方法的效果,增强广告效应,我们先看看我们未经整容前的URL:
文章列表页:www.vinqon.com/home.aspx?catid=3&page=2
第一次整容
第一个url奇丑无比,有两个参数,我们先把这两个参数组合一下,改成这样:
第一次整容:www.vinqon.com/home.aspx?catid=3-2
后台接收参数的动作要稍微改一下,可以把catid的值用spilt为数组或者用正则表达式把N个参数分离出来。
现在好了点,就算是有N个参数,也顶多这样子:www.vinqon.com/home.aspx?catid=1-6-12-56
或者用斜杠做分隔符,看起来更加伪:www.vinqon.com/home.aspx?catid=3/6/12/56
第二次&第三次整容
看看上面那个,前后斜杠塞了这么多字符,感觉很不爽,我们看得出,这里的catid五个字母没有什么意义,用一个c代替一下看看。
第二次整容:www.vinqon.com/home.aspx?c=3/6/12/56
还是很恶心,那个c不要到底行不行呢?试一下:
www.vinqon.com/home.aspx?3/6/12/56
这下懵了,没有了c,3/16/12/56是不是成了“名值对应”中的名呢?
试一下获取:Request.QueryString["3/16/12/56"],结果取了个null,这下奇怪了,服务器到底怎么理解这堆参数呢?
我又抱着尝试的心理,输出了一下:Request.QueryString.Count,结果竟然为1!这么说服务器还是认为这是一个参数的,我立刻用了另外一个方式获取这个参数::Request.QueryString[0]
这次终于可以把这堆参数取出来了。看来,当我们不用名值对应方式表示参数,而是直接用一段字符串表示,服务器会把它当作一个匿名参数。
现在,让我们看看第三次整容的效果:
第三次整容:www.vinqon.com/home.aspx?3/6/12/56
现在,这个样子的网址让人好接受一点了,但是,既然都做到这个地步了,可不可以再找找办法把那个恶心的文件后缀隐藏一下呢?
第四次&第五次整容
有一个很好的办法,在IIS中把home.aspx设置成默认首页,然后,url就可以变成这样了:
第四次整容:www.vinqon.com/?3/6/12/56
但是,这里带来了一个新的问题,每个页面都要这么帅,难道都设置成首页?即使这么设置了,也是行不通的。我这里的解决方案是,做一个跳转页面。现在我们的默认首页还是设置成Default.aspx,我们所要请求的每一个页面都作为一个参数解析。先看看效果:
第五次整容:www.vinqon.com/?home/3/6/12/56
Default页面会用正则获取第一个参数作为页面地址,从而找到跳转页面,为了保存页面这么帅,我们使用 Server.Transfer方法实现跳转,它可以把当前Request数据转移到目的页面,所以不需要大量修改原来页面解析参数的代码。
每一个页面的参数格式可能都不一样,所以我写了一堆Regax数组,一个个尝试匹配,这种方式可能不太好,以后研究参考一下MVC框架的实现方式,重写一下这部分。
private string ParseUrl(string url)
{
StringBuilder sb = new StringBuilder();
Regex[] reg = new Regex[]{
new Regex(@"(home|lab|books)/(\d*)-(\d*)"),
new Regex(@"(home|lab|books)/(\d*)()"),
new Regex(@"(edit|detail)/()()(\d*)"),
new Regex(@"(home|lab|books|edit|login)")
};
for (int i = 0; i < reg.Length; i++)
{
Match m = reg[i].Match(url);
if (m.Success)
{
sb.Append(m.Groups[1].Value + ".aspx?");
if (m.Groups[2].Value != "") { sb.Append("catid=" + m.Groups[2].Value); }
if (m.Groups[3].Value != "") { sb.Append("&index= " + m.Groups[3].Value); }
if (m.Groups[4].Value != "") { sb.Append("&id=" + m.Groups[4].Value); }
return sb.ToString();
}
}
return "home.aspx";
}
总结
其实这种玩意有很多副作用,跟ASP.Net MVC框架一样,不能正常PostBack,这意味了很多服务器控件不能正常使用,而且这个问题可能是不能解决的。其实我个人是比较喜欢直接用HTML标签带提交表单的,感觉比较原生态一点。这些问题后续再说吧。
最后,对比一下吧:
整容前:www.vinqon.com/home.aspx?catid=3&page=2
整容后:www.vinqon.com/?home/3-2
浙公网安备 33010602011771号