这两天一直在研究URL重写,通过几天的学习把学习笔记赶紧补上,呵呵,要养成好习惯嘛``
首先我们来看看URL重写都有哪些优点,大家为什么要做URL重写呢?相信大家都已经留意到了很多网站都采用“http://www.cnblogs.com/asidy/archive/2009/05/22/1486978.html”; “http://www.ShopPet.com/Pcategory/cat;” .....类似的目录,聪明的你一定想到了这些就是URL重写后的地址,看看上面的地址我们可以发现URL的路径变短了,从地址上可获取的信息更友好了,这样也便于用户的记忆和键入了,同时也隐藏了实际地址为网站提供了较高的安全性。不知大家对搜索引擎了解有多少,比如像”http://www.shop.com/product.aspx?id=1”,“http://www.shop.com/product.aspx?id=2”…………. “http://www.shop.com/product.aspx?id=n” 那么搜索引擎对这些地址是怎么处理的呢?可能大家也知道这个是被搜索引擎处理为同一地址既是“http://www.shop.com/product.aspx” ,带参数的页是不会作为独立的一个页面被收录的,而如果我们采用重写是可以把上面的地址重写为 “http://www.shop.com/product/1.aspx” 或 “http://www.shop.com/product/1”
等形式的,所以重写前的三个地址是都可以被收录的。
总结下URL的优点如下:
1缩短了URL的路径.
2URl的可读性更好,易于用户的记忆理解和键入。
3隐藏了实际地址从而提高了安全性。
4易于被搜索引擎收录
上面谈到的URL重写的优点是不是很诱人的哦,喜欢学习的你是不是特别想知道该如何实现URL重写呢?别着急慢慢来~~。在学习具体怎么做之前先搜罗下业界都有那些方法可实现URL重写。
URL重写的四种方法:
1利用request.pathinfo实现简单的重写规则。
相信不用我说大家也是很清楚的,像“http://www.shop.product.aspx/1这样的地址大家一定不陌生,request.pathinfo就可以获取页面的参数信息1。
2利用iisRewriter筛选器也就是urlrewriter.dll/urlrewriting.dll组件
3使用httpmodule
4使用httphandler
学习要要着中点,今天我们主要是看看利用httpmodle是如何实现URL重写的,利用httpmodle现在是有已经做好的组件了,而且做的也比较好了,就像是大家普遍采用的微软的组件Urlrewriter,那么我门主要是看看如何使用这个组件的:
第一大要点:要把组件urlrewriter.dll放进我们的项目中。
第二大要点:wenb.config中的配置
在<configuration>中插入
<configSections>
<section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter"/>
</configSections>
<RewriterConfig>
<Rules>
<RewriterRule>
<LookFor>~/d(/d{0,5})/.aspx</LookFor>
<SendTo>~/default.aspx?id=$1</SendTo>
</RewriterRule>
</Rules>
</RewriterConfig>
在 <httpHandlers>中插入
<add verb="*" path="*.aspx" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
第三大要点:配置IIS
好了一个最简单的URL重写就完成了,但只要你用心就会发现还有系列问题等着我们去改正,刚采用URL重写的网站还需要我们的改进优化。都有哪些问题呢?
1首先的一个问题是当你敲入重写后的地址发页面图片和样式不能正常显示了(主要是我们先前的网站采用的都是相对路径)。这个时候怎么办呢???办法是有多个的,比如:在页面开始部分引入<base..> 标签?(这个方法不好把,改动量也太大了,另外如果不做处理网页的真实地址也就很容易就被暴露出去了。。。)尽管办法不是很好但为解决图片不能正常显示的问题,原来的相对地址是不能用的,只能是用绝对地址了,相信不用我多说你也是很明白的。综合权衡了下还是准备把原有的网站做好代码优化了,原来的相对地址是必须都得给成相对的,另外原来的response.redirect跳转到其它页面的地址是最好不能用了(假如原来的是相对地址肯定不行的,会提示资源文件找不到,那改绝对的吧,想想将来维护发布网站吧,假如站点的目录结构发生变化,那我用配置节吧,一个两个还行那多个呢??)最后基于系列问题的考虑决定如下:把原来的response.redirect跳转尽量放页面中跳转,把原来整个站点的图片资源移动到根站点的同一文件夹放好,最后页面所有对图片引用的地方换成“/image”
2原来整个站点从一个页面到另一个页面全是用的是真实的地址,而不是重写后的地址,那整个站点还是重写前的,我们做了大半天的URL重写的工作没有体现出来呀,怎么办呢?为什么会这样呢,改不是我使用该组件的方法不对吧,我劝你还是不要怀疑自己,看下组件的源代码你就发现URL重写是个不可逆的过程,其实Urlwriter组件的原理就是借助httpmodle的HttpContext。RewritePath方法在服务器真正处理用户的请求前截获用户的请求然后来一个偷粮换柱的,这样用户在浏览器的地址并没有改变可实际显示的页面内容上另一个真实存在地址。了解了它的原理,那么就是组件没办法作到相互转换咯。哎,其实我们再写一个类也是可以做到到的,但是原来所有的页面基本上是要在程序中罗列的,工作量烦琐不说还有点得不尝失,所以还是请你不要白费力气了,另外原来的真实地址也没有被隐藏起来,所以建议你还是老老实实的把原来的真实地址逐个替换成重写后的地址。
3如果我们需要把整个站点的文件扩展名改成.html(伪静态),这个时候需要在我们的iisà站点属性—〉主目录—->配置 打开了应用程序配置窗体,添加一规则即是扩展名为”.html”;假如我们想把我们的扩展名改成任意扩展名就像”.deepcool”这个时候iis的配置操作如”.html”;如果我们要将我们的地址都变成是无扩展名的呢?这个时候在iis6中是很容易做到的。
4当我们做个了postback=true的操作(比如点击一个服务器的按纽)发现地址又变回重写前的了
在网上找了下解决办法,有如下方法:
一重写page所有的页都继承这个重写的page类
http://www.cnblogs.com/kaima/archive/2006/12/27/604758.html(老马博客)
using System;
using System.IO;
using System.Web;
using System.Web.UI;
namespace okpower.Utility
{
/// <summary>
/// URLRewrite 页面基类
/// 作者:Kai.Ma http://kaima.cnblogs.com
/// </summary>
public class URLRewritePage : Page
{
public URLRewritePage()
{
}
protected override void Render(HtmlTextWriter writer)
{
writer = new FormFixerHtmlTextWriter(writer.InnerWriter);
base.Render(writer);
}
}
internal class FormFixerHtmlTextWriter : System.Web.UI.HtmlTextWriter
{
private string _url;
internal FormFixerHtmlTextWriter(TextWriter writer)
: base(writer)
{
_url = HttpContext.Current.Request.RawUrl;
}
public override void WriteAttribute(string name, string value, bool encode)
{
// 如果当前输出的属性为form标记的action属性,则将其值替换为重写后的虚假URL
if (_url != null && string.Compare(name, "action", true) == 0)
{
value = _url;
}
base.WriteAttribute(name, value, encode);
}
}
}
二重写HtmlForm
http://www.cnblogs.com/JeffreyZhao/archive/2006/12/27/604373.html(老赵)
继承HtmlForm类实现自己的From
然后我们的所有页面都得修改如下
三借助"浏览器文件"及重写
http://www.cnblogs.com/smh188/articles/841050.html
RewriteForm.browser 内容如下
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
adapterType="Kuang.HtmlFormAdapter" />
</controlAdapters>
</browser>
</browsers>
添加两个类如下:
但以上三中方法似乎都没有解决好urlwriter.dll导致form中的action属性改变(ajax中的updatepanel是问题的关键)问题???
使用我们自己实现的Form
<%@ Register TagPrefix="skm" Namespace="ActionlessForm"
Assembly="ActionlessForm" %>
...
<skm:Form id="Form1" method="post" runat="server">
...
</skm:Form>
namespace ActionlessForm {
public class Form : System.Web.UI.HtmlControls.HtmlForm
{
protected override void RenderAttributes(HtmlTextWriter writer)
{
writer.WriteAttribute("name", this.Name);
base.Attributes.Remove("name");
writer.WriteAttribute("method", this.Method);
base.Attributes.Remove("method");
this.Attributes.Render(writer);
base.Attributes.Remove("action");
if (base.ID != null)
writer.WriteAttribute("id", base.ClientID);
}
}
}