您现在的位置是:首页 > cms教程 > Discuz教程Discuz教程
Discuz的NT中URL地址重写URLRewrite介绍
雪青2025-06-25Discuz教程已有人查阅
导读在Discuz!NT中的前台页面访问(特别是aspx)是被HttpModule接管的,所以大家在Discuz.Web项目的目录下看到的唯一"aspx文件"是index.aspx,而所有其它前台页面都有“/aspx/”
在Discuz!NT中的前台页面访问(特别是aspx)是被HttpModule接管的,所以大家在Discuz.Web项目的目录下看到的唯一"aspx文件"是index.aspx,而所有其它前台页面都有“/aspx/”文件夹下的相应的子目录中,而这些子目录名称是与后台所“生成”的模板存在对应关系的。而这种“关系”的绑定是通过dnt_templates(模板数据表)来进行关联的。而有关模板机制的文章详见:“Discuz!NT 模板机制分析”一文。今天所要说的其实是模板机制的“延续”,当然这种“延续”仅是我个人的观点。因为地址重写最终要绑定的路径,恰恰与模板机制是有着前后呼应的关系。首先请大家看一下
相信对于那些以前做过“URL重写”的朋友看到这一行配置的第一反映可能就是要去Discuz.Forum.HttpModule类中一看究竟。同时考虑到在<httpModules>配置节中加入处理的资料在网上有许多,所以这里就不再多费唇舌了。
另外如果大家感兴趣味的话,也可以抽空看看我的这篇文章,"NET框架中的 Observer 模式"。虽然该文是我在挖.net底层代码时是写的一些个人想法,可读性不高,但我相信会对大家有所帮助的:)好了,下面让我们看一下在Discuz.Forum项目中的HttpModule类中的一些信息,看看URL重写到底如何实现:)
同时大家看到的OnlineUsers.ResetOnlineList()方法主要是用于“重置(复位)在线表”,而有关“在线用户”的功能我会在以后专门写文章来加以介绍,所以这里大家只要知道它要干的事(代码如下)即可:)
成可访问的信息对象。形如:
到目前,我们知道了要通过“urls.config”文件来进行伪URL重写,那么这个文件中的数据到底是什么样子呢,下面就是在成功安装discuz!nt 2.0产品之后的文件内容:
showforum.aspx(版块列表),showtopic.aspx(主题列表),userinfo.aspx(用户信息),rss.aspx,虽然不多,但已基本满足了设置需要。而设置(配置)管理的页面在后台的“全局”-->“常规选项”-->“基本设置”-->“编辑伪静态url替换规则”,相信聊到这里大家对我们产品的这项功能应该有个大概认识了,但这不并是全部的设置,因为如果要接管形如"showforum-1-2.htm"这样的页面,是必须要到IIS里去“搞一把”的。因为默认的IIS中对htm(html)的处理是无法实现将上面的链接转成“showforum.aspx?forumid=1&page=2”的形式的,所以这里要参考一下官方文档(使用伪Url地址)中的方法。
下面再接着聊一下关于与第三方产品“整和”的问题。因为目前大多数采用 .net技术开发的主流产品(如博客园等)都会或多或少使用与本文类似或相同的做法来实现地址重写功能。比如:继承并实现IHttpHandler接口。
当然我们的产品所采用实现IHttpModule的方式会比IHttpHandler更早一步被 IIS进行处理。所以如果出现了这种情况,我个人建议是改动我们产品中的代码,通过在上述 ReUrl_BeginRequest事件中加入条件分支(第三方程序的伪地址规则)来实现“地址重写整合”;当然如果第三方的 (重写)规则太复杂的话,也可以在我们产品的相应代码中加入条件分支(只要出现第三方请求的链接页面或指定路径时),但不作任何处理(直接绿灯放行),这样就会转入到第三方的伪URL重写规则代码的“势力范围”内了。
当然如果第三方也使用类似IHttpModule的实现方式,则要看是谁的配置先出现在web.config中的相应配置节中了。因为“先入为主”嘛,如果先后顺序已明确的话,那么先被加载的HttpModule 模块就要做一下变动了,以便不会干扰后面的HttpModule模块的正常运行了。因为我手上这方面的实例也不多,所以只能在这里聊聊我本人的一些看法,相信随着官方“整合案例” 的增加,这方面的资料会得到更大的补充。
相信对于那些以前做过“URL重写”的朋友看到这一行配置的第一反映可能就是要去Discuz.Forum.HttpModule类中一看究竟。同时考虑到在<httpModules>配置节中加入处理的资料在网上有许多,所以这里就不再多费唇舌了。
另外如果大家感兴趣味的话,也可以抽空看看我的这篇文章,"NET框架中的 Observer 模式"。虽然该文是我在挖.net底层代码时是写的一些个人想法,可读性不高,但我相信会对大家有所帮助的:)好了,下面让我们看一下在Discuz.Forum项目中的HttpModule类中的一些信息,看看URL重写到底如何实现:)
1/// <summary>
2 /// 论坛HttpModule类
3 /// </summary>
4 public class HttpModule : System.Web.IHttpModule
5 {
6 /// <summary>
7 /// 实现接口的Init方法
8 /// </summary>
9 /// <param name="context"></param>
10 public void Init(HttpApplication context)
11 {
12 OnlineUsers.ResetOnlineList();
13 context.BeginRequest += new EventHandler(ReUrl_BeginRequest);
14 }
上面代码中的Init(HttpApplication context)是HttpModule类进行操作的入口,所有实现System.Web.IHttpModule 接口的类都必须实现这个函数。同时大家看到的OnlineUsers.ResetOnlineList()方法主要是用于“重置(复位)在线表”,而有关“在线用户”的功能我会在以后专门写文章来加以介绍,所以这里大家只要知道它要干的事(代码如下)即可:)
1 /// <summary>
2 /// 复位在线表, 如果系统未重启, 仅是应用程序重新启动, 则不会重新创建
3 /// </summary>
4 /// <returns></returns>
5 public static int ResetOnlineList()
6 {
7 try
8 {
9 // 取得在线表之后一条记录的tickcount字段 (因为本功能不要求特别精确)
10 //int tickcount = DatabaseProvider.GetInstance().GetLastTickCount();
11 // 如果距离现在系统运行时间小于10分钟
12 if (System.Environment.TickCount < 600000)
13 {
14 return InitOnlineList();
15 }
16 return -1;
17 }
18 catch
19 {
20 try
21 {
22 return InitOnlineList();
23 }
24 catch
25 {
26 return -1;
27 }
28 }
29
30 }
而紧随其后的事件绑定代码就是一个关键点了,形如:
context.BeginRequest += new EventHandler(ReUrl_BeginRequest);
因为当通过浏览器提交请求时,IIS都会接管请求进行相应的操作(详见DUDU的文章:"ASP.NET 2.0运行时简要分析")后,最终通过Web.config中的相应配置节(上图所示)来执行用户预定的处理操作。而我们的代码就在ReUrl_BeginRequest事件中(代码如下,详情见注释):
1/// <summary>
2 /// 重写Url
3 /// </summary>
4 /// <param name="sender">事件的源</param>
5 /// <param name="e">包含事件数据的 EventArgs</param>
6 private void ReUrl_BeginRequest(object sender, EventArgs e)
7 {
8 //获取基本配置信息
9 BaseConfigInfo baseconfig = BaseConfigProvider.Instance();
10
11 if (baseconfig == null)
12 {
13 return;
14 }
15
16 //得到论坛配置信息
17 GeneralConfigInfo config = GeneralConfigs.GetConfig();
18 HttpContext context = ((HttpApplication)sender).Context;
19 string forumPath = baseconfig.Forumpath.ToLower();
20
21 string requestPath = context.Request.Path.ToLower();
22
23 if (requestPath.StartsWith(forumPath))
24 {
25 if (requestPath.Substring(forumPath.Length).IndexOf("/") == -1)
26 {
27 // 声明并设置默认论坛模板
28 string strTemplateid = config.Templateid.ToString();
29 // 判断COOKIE中模板是否是系统当前的有效(已入库)模板
30 if (Utils.InArray(Utils.GetCookie(Utils.GetTemplateCookieName()),
31 Templates.GetValidTemplateIDList()))
32 {
33 strTemplateid = Utils.GetCookie(Utils.GetTemplateCookieName());
34 }
35
36 //当访问的是首页时
37 if (requestPath.EndsWith("/index.aspx"))
38 {
39 //当配置文件中未指定首页时,则将forumindex.aspx做为首页并重写路径
40 if (config.Indexpage == 0)
41 {
42
43 context.RewritePath(forumPath + "aspx/" + strTemplateid + "/forumindex.aspx");
44 }
45 else //否则使用聚合首页来做为网站首页并重写路径
46 {
47
48 context.RewritePath(forumPath + "aspx/" + strTemplateid + "/website.aspx");
49 }
50
51 return;
52 }
53
54
55 //当使用伪aspx, 如:showforum-1.aspx等.
56 if (config.Aspxrewrite == 1)
57 {
58 //获取后台设置的可以使用的伪aspx设置.
59 //SiteUrls.GetSiteUrls()类和方法说明见下文
60 foreach (SiteUrls.URLRewrite url in SiteUrls.GetSiteUrls().Urls)
61 {
62 //进行正则匹配,来看访问页面是否是用户定义的伪URL地址
63 if (Regex.IsMatch(requestPath, url.Pattern, Utils.GetRegexCompiledOptions() | RegexOptions.IgnoreCase))
64 {
65 string newUrl = Regex.Replace(requestPath.Substring(context.Request.Path.LastIndexOf("/")), url.Pattern, url.QueryString, Utils.GetRegexCompiledOptions() | RegexOptions.IgnoreCase);
66
67 context.RewritePath(forumPath + "aspx/" + strTemplateid + url.Page, string.Empty, newUrl);
68 return;
69 }
70 }
71 }
72
73
74
75 context.RewritePath(forumPath + "aspx/" + strTemplateid + requestPath.Substring(context.Request.Path.LastIndexOf("/")), string.Empty, context.Request.QueryString.ToString());
76 }
77 //当前请求路径是“论坛路径/archiver(简洁版路径)/"下时.
78 else if (requestPath.StartsWith(forumPath + "archiver/"))
79 {
80
81
82 return;
83 }
84 //当前请求路径是“论坛路径/tools/(论坛工具页面如:rss,sitemap,help等)”请求时
85 else if (requestPath.StartsWith(forumPath + "tools/"))
86 {
87
88 return;
89 }
90
91 }
92 }
93
94
这样就实现了伪URL的动态转换(地址重写)。而相应的“SiteUrls”类则是对伪URL设置信息进行访问读取的“封装类”,目的就是要将Discuz.Web项目中config文件夹下的urls.config文件转换成可访问的信息对象。形如:
1/// <summary>
2 /// 站点伪Url信息类
3 /// </summary>
4 public class SiteUrls
5 {
6 内部属性和方法
66
67 //获取伪URL设置对象的实例
68 public static SiteUrls GetSiteUrls()
69 {
70 if (instance == null)
71 {
72 lock (lockHelper)
73 {
74 if (instance == null)
75 {
76 instance = new SiteUrls();
77 }
78 }
79 }
80 return instance;
81
82 }
83
84 public static void SetInstance(SiteUrls anInstance)
85 {
86 if (anInstance != null)
87 instance = anInstance;
88 }
89
90 public static void SetInstance()
91 {
92 SetInstance(new SiteUrls());
93 }
94
95
96 /// <summary>
97 /// 重写伪地址(内部类),用于声明和封装对象
98 /// </summary>
99 public class URLRewrite
100 {
101 成员变量
154
155 构造函数
164 }
165
166 }
因为代码很简单,这里就不再另行说明了。到目前,我们知道了要通过“urls.config”文件来进行伪URL重写,那么这个文件中的数据到底是什么样子呢,下面就是在成功安装discuz!nt 2.0产品之后的文件内容:
<?xml version="1.0" encoding="utf-8" ?>
<urls>
<rewrite name="showforum"path="/showforum-{0}-{1}.aspx"pattern = "/showforum-(\d+)(-(\d+))?.aspx"page="/showforum.aspx"querystring="forumid=$1^page=$3" />
<rewrite name="showtopic"path="/showtopic-{0}-{1}.aspx"pattern = "/showtopic-(\d+)(-(\d+))?.aspx"page="/showtopic.aspx"querystring="topicid=$1^page=$3" />
<rewrite name="userinfo"path="/userinfo-{0}.aspx"pattern = "/userinfo-(\d+)*.aspx"page="/userinfo.aspx" querystring="userid=$1" />
<rewrite name="rss" path="/rss-{0}.aspx" pattern = "/rss-(\d+)?.aspx" page="/rss.aspx" querystring="forumid=$1" />
<rewrite name="spacerss" path="/spacerss-{0}.aspx" pattern="/spacerss(-(\d+))?.aspx(\?.*?)?" page="/rss.aspx" querystring="uid=$2&type=space" />
<rewrite name="photorss" path="/photorss-{0}.aspx" pattern="/photorss(-(\d+))?.aspx(\?.*?)?" page="/rss.aspx" querystring="uid=$2&type=photo" />
</urls>
大家看到了吧。就目前而言伪URL重写的页面(page节点)包括如下几个:showforum.aspx(版块列表),showtopic.aspx(主题列表),userinfo.aspx(用户信息),rss.aspx,虽然不多,但已基本满足了设置需要。而设置(配置)管理的页面在后台的“全局”-->“常规选项”-->“基本设置”-->“编辑伪静态url替换规则”,相信聊到这里大家对我们产品的这项功能应该有个大概认识了,但这不并是全部的设置,因为如果要接管形如"showforum-1-2.htm"这样的页面,是必须要到IIS里去“搞一把”的。因为默认的IIS中对htm(html)的处理是无法实现将上面的链接转成“showforum.aspx?forumid=1&page=2”的形式的,所以这里要参考一下官方文档(使用伪Url地址)中的方法。
下面再接着聊一下关于与第三方产品“整和”的问题。因为目前大多数采用 .net技术开发的主流产品(如博客园等)都会或多或少使用与本文类似或相同的做法来实现地址重写功能。比如:继承并实现IHttpHandler接口。
当然我们的产品所采用实现IHttpModule的方式会比IHttpHandler更早一步被 IIS进行处理。所以如果出现了这种情况,我个人建议是改动我们产品中的代码,通过在上述 ReUrl_BeginRequest事件中加入条件分支(第三方程序的伪地址规则)来实现“地址重写整合”;当然如果第三方的 (重写)规则太复杂的话,也可以在我们产品的相应代码中加入条件分支(只要出现第三方请求的链接页面或指定路径时),但不作任何处理(直接绿灯放行),这样就会转入到第三方的伪URL重写规则代码的“势力范围”内了。
当然如果第三方也使用类似IHttpModule的实现方式,则要看是谁的配置先出现在web.config中的相应配置节中了。因为“先入为主”嘛,如果先后顺序已明确的话,那么先被加载的HttpModule 模块就要做一下变动了,以便不会干扰后面的HttpModule模块的正常运行了。因为我手上这方面的实例也不多,所以只能在这里聊聊我本人的一些看法,相信随着官方“整合案例” 的增加,这方面的资料会得到更大的补充。
本文标签:
很赞哦! ()
相关教程
图文教程
Discuz积分商城功能使用和运营方法
在Discuz论坛中,积分商城是一个非常有用的功能,它不仅可以激励用户的活跃度,还能为论坛带来额外的收入。那么,如何配置和运营Discuz的积分商城呢?
CentOs7搭建论坛Discuz_X3.2的步骤方法
由于公司项目需要一个互动平台,可以发起活动,发消息留言,讨论过后发现这竟然是一个论坛的功能。 于是就不打算耗费功夫开发相关功能,直接另外搭一套BBS算球。。。 一直觉得搭建B
discuz门户文章页面模板修改方式实例
修改内容:view.htm1.文章标题,模板代码文章标题, 前台代码2.文章信息,模板代码:文章信息:前台代码3.相关阅读 模板代码
ThinkPHP和Discuz怎么整合
以下是Discuz6的整合方法,在模板中新增登陆模板,路径为Tpl/default/Public/Login.html这里把官方教程中的模板贴出来,省的再去找了:
相关源码
-
(自适应)工业机械制造设备网站pbootcms模板下载为机械制造、工业设备类企业设计,特别适合各类机械设备、生产线、工业自动化产品展示。采用响应式技术,确保在不同设备上都能清晰展示机械产品的技术参数和细节特点。查看源码 -
(自适应)品牌策划高端设计公司网站pbootcms模板免费下载本模板为品牌策划与设计公司打造,基于PbootCMS内核开发,充分考虑了创意设计行业的视觉展示需求。模板设计风格现代简约,布局合理清晰,呈现设计作品与专业服务,帮助设计公司展示创意实力并吸引潜在客户。查看源码 -
(PC+WAP)茶叶茶艺茶道茶文化pbootcms模网站源码下载本模板基于PbootCMS系统开发,为茶叶企业、茶艺培训机构设计,特别适合展示茶产品、茶道文化等内容。采用响应式技术,确保在不同设备上都能呈现优雅的茶文化氛围。查看源码 -
(自适应)WordPress主题SEO自媒体博客资讯模板RabbitV2.0Rabbit v2.0主题专注于网站搜索引擎优化需求,为博客、自媒体及资讯类网站提供专业的SEO技术解决方案。该主题从架构设计到功能实现均围绕搜索引擎优化理念展开。查看源码 -
(PC+WAP)安保服务保安保镖模板免费下载本模板基于PbootCMS内核开发,为安保服务企业量身打造。设计风格严谨专业,突出安保行业的安全、可靠特性,展示企业服务项目与实力。采用响应式设计,PC与移动端数据同步,管理便捷。模板布局合理查看源码 -
(响应式)wordpress模板VieuV4.5主题资讯自媒体博客源码Vieu主题专注于个人博客与企业展示场景,采用响应式设计确保在手机、电脑、平板等多设备上的展示。主题集成会员中心、投稿系统、内容保护等实用功能,满足现代博客网站的建设需求。查看源码
| 分享笔记 (共有 篇笔记) |
