一、 介绍 2
二、 相关技术 2
1. ISAPI 2
2. 利用程序进行URL重写 2
三、 技术样例 2
1. 直接使用HTTPCONTEXT.REWRITEPATH 2
2. 使用HTTPMODULE进行URL重写 3
一、 介绍
顾名思义, “url重写”就是将原先的网页url变换成另一种表现形式. 现在的网站系统为了适应google, yahoo等搜索引擎的搜索规则, 同时也为了站点url表现的更直观, 更friendly, 纷纷采用url重写技术,典型的url重写技术有: ISAPI, (asp.net , java…)url重写技术, 这里主要介绍asp.net中的url重写技术.
二、 相关技术
1. ISAPI
这是利用iis进行url重写的技术, 需要利用iis的api函数, 然后自己开发一个iis过滤器,从而打到url重写的目的
2. 利用程序进行url重写
现在很多程序开发语言都有自己的url重写接口, 可以很方便的在程序中直接对url进行重写. 像asp.net 的HttpContext.RewritePath; java的url rewrite filter等等
三、 技术样例
Asp.net中实现url重写有两种方式: 一是在程序中直接用HttpContext.RewritePath直接将一段url重写为规定格式的url; 另一种是重写HttpModule来进行url的重写
1. 直接使用HttpContext.RewritePath
1) 当前有两个页面: Default.aspx和Result.aspx, 需要发送一个请求到default.aspx页面, 显示result.aspx页面的结果.
2) 在页面请求的时候url的形式是这样的:
这是经过组织的url, http://www.onlinehealthcentre.co.uk这是站点域名, showResult是参数名, yes是参数值
3) 在default.aspx页面接收的时候解析这个url, 获得参数名和值, 然后在default.aspx.cs页面后台代码中加上转向语句:
If (showResult.Equals(“yes”))
{
Context.RewritePath(“Result.aspx”);
}
4) 这样, 当前页面的url不会变, 但是页面的内容已经变成了Result.aspx页面的内容, 也就是说页面实际上已经转向到了Result.aspx页面, 只不过是url没有改变而已
2. 使用HttpModule进行Url重写
1) 首先, 要在web.config的System.Web节中添加下面的配置节:
<httpModules>
<add name="ModuleRewriter" type="URLRewriter.ModuleRewriter, URLRewriter" />
</httpModules>
name:使用的唯一索引名(friendly name)
type: 重写的httpModule的类名和dll名称
2) 然后在web.config中加入下面的重写规则:
<RewriterConfig>
<Rules>
<RewriterRule>
<LookFor>要查找的模式</LookFor>
<SendTo>要用来替换模式的字符串</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>要查找的模式</LookFor>
<SendTo>要用来替换模式的字符串</SendTo>
</RewriterRule>
</Rules>
</RewriterConfig>
LookFor和SendTo都是用正则表达式来标明url的匹配规则的
3) 新建BaseModuleRewriter基类, 实现了IHttpModule接口
using System;
using System.Web;
namespace URLRewriter
{
public abstract class BaseModuleRewriter : IHttpModule
{
public virtual void Init(HttpApplication app)
{
app.AuthorizeRequest += new EventHandler(this.BaseModuleRewriter_AuthorizeRequest);
}
public virtual void Dispose()
{}
/// <summary>
///重写事件
/// </summary>
protected virtual void BaseModuleRewriter_AuthorizeRequest(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication) sender;
Rewrite(app.Request.Path, app);
}
/// <summary>
///执行重写
/// </summary>
protected abstract void Rewrite(string requestedPath, HttpApplication app);
}
}
4) 新建扩展类ModuleRewriter, 继承自BaseModuleRewriter
using System;
using System.Text.RegularExpressions;
using System.Configuration;
using URLRewriter.Config;
namespace URLRewriter
{
public class ModuleRewriter : BaseModuleRewriter
{
/// <summary>
/// 覆写Rewrite方法, 提供自定义的url重写规则
/// </summary>
/// <param name="requestedRawUrl">请求的url地址</param>
/// <param name="app"> HttpApplication 实例</param>
protected override void Rewrite(string requestedPath, System.Web.HttpApplication app)
{
// 获取配置信息集合
RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules;
for(int i = 0; i < rules.Count; i++)
{
// 获取url匹配的模式
string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor) + "$";
// 创建正则对象
Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);
if (re.IsMatch(requestedPath)) // 如果url匹配定义的规则
{
// 获取对应的转向(重写)地址
string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
// 执行重写
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
break;
}
}
}
}
}
5) 创建Url重写工具类RewriterUtils, 此类提供一些供url重写使用的静态方法
using System;
using System.Web;
namespace URLRewriter
{
internal class RewriterUtils
{
internal static void RewriteUrl(HttpContext context, string sendToUrl)
{
string x, y;
RewriteUrl(context, sendToUrl, out x, out y);
}
/// <summary>
/// 重写带参数的url
/// </summary>
/// <param name="context"> </param>
/// <param name="sendToUrl"> </param>
/// <param name="sendToUrlLessQString">参数字符串</param>
/// <param name="filePath"> </param>
internal static void RewriteUrl(HttpContext context, string sendToUrl, out string sendToUrlLessQString, out string filePath)
{
if (context.Request.QueryString.Count > 0)
{
if (sendToUrl.IndexOf('?') != -1)
sendToUrl += "&" + context.Request.QueryString.ToString();
else
sendToUrl += "?" + context.Request.QueryString.ToString();
}
string queryString = String.Empty;
sendToUrlLessQString = sendToUrl;
if (sendToUrl.IndexOf('?') > 0)
{
sendToUrlLessQString = sendToUrl.Substring(0, sendToUrl.IndexOf('?'));
queryString = sendToUrl.Substring(sendToUrl.IndexOf('?') + 1);
}
filePath = string.Empty;
filePath = context.Server.MapPath(sendToUrlLessQString);
context.RewritePath(sendToUrlLessQString, String.Empty, queryString);
}
internal static string ResolveUrl(string appPath, string url)
{
if (url.Length == 0 || url[0] != '~') //如果文件路径里面没有“~”字符
{
return url;
}
else
{
if (url.Length == 1) //如果路径仅仅是“~”
{
return appPath;
}
if (url[1] == '/' || url[1] == '\\')
{
// 获取像 ~/ or ~\这样模式的url
if (appPath.Length > 1)
{
return appPath + "/" + url.Substring(2);
}
else
{
return "/" + url.Substring(2);
}
}
else
{
if (appPath.Length > 1)
{
return appPath + "/" + url.Substring(1);
}
else
{
return appPath + url.Substring(1);
}
}
}
}
}
}
6) 创建重写规则集合类:RewriterRuleCollection
using System;
using System.Collections;
namespace URLRewriter.Config
{
[Serializable()]
public class RewriterRuleCollection : CollectionBase
{
public virtual void Add(RewriterRule r)
{
this.InnerList.Add(r);
}
public RewriterRule this[int index]
{
get
{
return (RewriterRule) this.InnerList[index];
}
set
{
this.InnerList[index] = value;
}
}
}
}
7) 创建获取配置节信息类: RewriterConfiguration
using System;
using System.Web;
using System.Web.Caching;
using System.Configuration;
using System.Xml.Serialization;
namespace URLRewriter.Config
{
[Serializable()]
[XmlRoot("RewriterConfig")]
public class RewriterConfiguration
{
private RewriterRuleCollection rules;
public static RewriterConfiguration GetConfig()
{
if (HttpContext.Current.Cache["RewriterConfig"] == null)
{
HttpContext.Current.Cache.Insert("RewriterConfig", ConfigurationSettings.GetConfig("RewriterConfig"));
}
return (RewriterConfiguration) HttpContext.Current.Cache["RewriterConfig"];
}
public RewriterRuleCollection Rules
{
get
{
return rules;
}
set
{
rules = value;
}
}
}
}
8) 创建重写规则实体类: RewriterRule
using System;
namespace URLRewriter.Config
{
[Serializable()]
public class RewriterRule
{
private string lookFor, sendTo;
public string LookFor
{
get
{
return lookFor;
}
set
{
lookFor = value;
}
}
public string SendTo
{
get
{
return sendTo;
}
set
{
sendTo = value;
}
}
}
}
这样, 就可以在站定中实行url重写了, 站点在请求时会首先加载BaseModuleRewriter类, 然后查找匹配的url重写规则进行url重写。