Url地址重写
一 什么是url重写
URL 重写是截取传入 Web 请求并自动将请求重定向到其他 URL 的过程。比如浏览器发来请求 hostname/101.aspx ,服务器自动将这个请求中定向为http://hostname/list.aspx ?id=101。 会人为改为 hostname/101.shtml
url重写的优点在于:
l 缩短url,隐藏实际路径提高安全性
l 易于用户记忆和键入。
l 易于被搜索引擎收录
二 实现url重写的基本方法
1. 创建类项目UrlRewriter,项目中增加三个类URLRewriter.Config.cs,URLRewriter.Form.cs,URLRewriter.Module.cs
using System;
using System.Configuration;
using System.Collections; namespace URLRewriter.Config
{
// Define a custom section containing a simple element and a collection of the same element.
// It uses two custom types: UrlsCollection and UrlsConfigElement.
public class UrlsConfig
{
public static UrlsSection GetConfig()
{
return (UrlsSection)System.Configuration.ConfigurationManager.GetSection("CustomConfiguration");
} } public class UrlsSection : ConfigurationSection
{
[ConfigurationProperty("urls",IsDefaultCollection = false)]
public UrlsCollection Urls
{
get
{
return (UrlsCollection)this["urls"];
}
}
} // Define the UrlsCollection that contains UrlsConfigElement elements.
public class UrlsCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new UrlConfigElement();
}
protected override Object GetElementKey(ConfigurationElement element)
{
return ((UrlConfigElement)element).VirtualUrl;
} public UrlConfigElement this[int index]
{
get
{
return (UrlConfigElement)BaseGet(index);
}
} } // Define the UrlConfigElement.
public class UrlConfigElement : ConfigurationElement
{ [ConfigurationProperty("virtualUrl", IsRequired = true)]
public string VirtualUrl
{
get
{
return (string)this["virtualUrl"];
}
set
{
this["virtualUrl"] = value;
}
} [ConfigurationProperty("destinationUrl", IsRequired = true)]
public string DestinationUrl
{
get
{
return (string)this["destinationUrl"];
}
set
{
this["destinationUrl"] = value;
}
}
}
} using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls; /// <summary>
/// FormRewriter 的摘要说明
/// </summary>
namespace URLRewriter.Form
{
public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
{
public FormRewriterControlAdapter()
{
} protected override void Render(HtmlTextWriter writer)
{
base.Render(new RewriteFormHtmlTextWriter(writer));
}
} public class RewriteFormHtmlTextWriter : HtmlTextWriter
{
public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
: base(writer)
{
base.InnerWriter = writer.InnerWriter;
}
public RewriteFormHtmlTextWriter(System.IO.TextWriter writer)
: base(writer)
{
base.InnerWriter = writer;
} public override void WriteAttribute(string name, string value, bool fEncode)
{
//If the attribute we are writing is the "action" attribute, and we are not on a sub-control,
//then replace the value to write with the raw URL of the request - which ensures that we'll
//preserve the PathInfo value on postback scenarios
if (name == "action")
{
HttpContext context = HttpContext.Current;
if (context.Items["ActionAlreadyWritten"] == null)
{
//We will use the Request.RawUrl property within ASP.NET to retrieve the origional
//URL before it was re-written.
value = context.Request.RawUrl;
//Indicate that we've already rewritten the <form>'s action attribute to prevent
//us from rewriting a sub-control under the <form> control
context.Items["ActionAlreadyWritten"] = true;
}
}
base.WriteAttribute(name, value, fEncode);
}
} } using System;
using System.Web;
using System.Text.RegularExpressions;
using System.Configuration;
using URLRewriter.Config; namespace URLRewriter
{
public class RewriterModule : IHttpModule
{
public void Init(HttpApplication app)
{
// WARNING! This does not work with Windows authentication!
// If you are using Windows authentication, change to app.BeginRequest
app.AuthorizeRequest += new EventHandler(this.URLRewriter);
} protected void URLRewriter(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication) sender;
string requestedPath = app.Request.Path; // get the configuration rules
UrlsCollection rules = UrlsConfig.GetConfig().Urls; for (int i = ; i < rules.Count; i++)
{
// get the pattern to look for, and Resolve the Url (convert ~ into the appropriate directory)
string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].VirtualUrl) + "$"; Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);
if (re.IsMatch(requestedPath))
{
string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].DestinationUrl));
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
break;
}
} } public void Dispose() { }
} /// <summary>
/// Provides utility helper methods for the rewriting HttpModule and HttpHandler.
/// </summary>
/// <remarks>This class is marked as internal, meaning only classes in the same assembly will be
/// able to access its methods.</remarks>
internal class RewriterUtils
{
#region RewriteUrl
/// <summary>
/// Rewrite's a URL using <b>HttpContext.RewriteUrl()</b>.
/// </summary>
/// <param name="context">The HttpContext object to rewrite the URL to.</param>
/// <param name="sendToUrl">The URL to rewrite to.</param>
internal static void RewriteUrl(HttpContext context, string sendToUrl)
{
string x, y;
RewriteUrl(context, sendToUrl, out x, out y);
} /// <summary>
/// Rewrite's a URL using <b>HttpContext.RewriteUrl()</b>.
/// </summary>
/// <param name="context">The HttpContext object to rewrite the URL to.</param>
/// <param name="sendToUrl">The URL to rewrite to.</param>
/// <param name="sendToUrlLessQString">Returns the value of sendToUrl stripped of the querystring.</param>
/// <param name="filePath">Returns the physical file path to the requested page.</param>
internal static void RewriteUrl(HttpContext context, string sendToUrl, out string sendToUrlLessQString, out string filePath)
{
// see if we need to add any extra querystring information
if (context.Request.QueryString.Count > )
{
if (sendToUrl.IndexOf('?') != -)
sendToUrl += "&" + context.Request.QueryString.ToString();
else
sendToUrl += "?" + context.Request.QueryString.ToString();
} // first strip the querystring, if any
string queryString = String.Empty;
sendToUrlLessQString = sendToUrl;
if (sendToUrl.IndexOf('?') > )
{
sendToUrlLessQString = sendToUrl.Substring(, sendToUrl.IndexOf('?'));
queryString = sendToUrl.Substring(sendToUrl.IndexOf('?') + );
} // grab the file's physical path
filePath = string.Empty;
filePath = context.Server.MapPath(sendToUrlLessQString); // rewrite the path
context.RewritePath(sendToUrlLessQString, String.Empty, queryString);
}
#endregion /// <summary>
/// Converts a URL into one that is usable on the requesting client.
/// </summary>
/// <remarks>Converts ~ to the requesting application path. Mimics the behavior of the
/// <b>Control.ResolveUrl()</b> method, which is often used by control developers.</remarks>
/// <param name="appPath">The application path.</param>
/// <param name="url">The URL, which might contain ~.</param>
/// <returns>A resolved URL. If the input parameter <b>url</b> contains ~, it is replaced with the
/// value of the <b>appPath</b> parameter.</returns>
internal static string ResolveUrl(string appPath, string url)
{
if (url.Length == || url[] != '~')
return url; // there is no ~ in the first character position, just return the url
else
{
if (url.Length == )
return appPath; // there is just the ~ in the URL, return the appPath
if (url[] == '/' || url[] == '//')
{
// url looks like ~/ or ~/
if (appPath.Length > )
return appPath + "/" + url.Substring();
else
return "/" + url.Substring();
}
else
{
// url looks like ~something
if (appPath.Length > )
return appPath + "/" + url.Substring();
else
return appPath + url.Substring();
}
}
}
} }
.在web.config里设置如下: Code
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="CustomConfiguration" type="URLRewriter.Config.UrlsSection, URLRewriter" />
</configSections> <CustomConfiguration>
<urls>
<add virtualUrl="~/microsoft*.*" destinationUrl="~/default.aspx?id=abc" />
<add virtualUrl="~/microsoft*" destinationUrl="~/default.aspx" />
<add virtualUrl="~/m/i/c/rosoft.aspx" destinationUrl="~/default.aspx" /> <add virtualUrl="~/cc*.*" destinationUrl="~/default2.aspx?id=11" />
</urls>
</CustomConfiguration> <system.web>
<httpModules>
<add type="URLRewriter.RewriterModule, URLRewriter" name="RewriterModule"/>
</httpModules>
<authentication mode="Forms"/>
</system.web>
</configuration> .处理回发
在重写后的url里如果产生回发,例如有一个按钮,又调用了该被重写的aspx,用户浏览器中将会显示该aspx文件实际的地址,也就是http://hostname/default.aspx?id=11。但从用户的角度考虑,如 果单击按钮时突然看到 URL 更改会使他们感到不安。因此必须解决这个问题。
自己定义一个Actionlessform类,在aspx中不再使用系统提供的form 标记 Code
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel; namespace ActionlessForm
{
/// <summary>
/// The Form class extends the HtmlForm HTML control by overriding its RenderAttributes()
/// method and NOT emitting an action attribute.
/// </summary>
public class Form : System.Web.UI.HtmlControls.HtmlForm
{
/// <summary>
/// The RenderAttributes method adds the attributes to the rendered <form> tag.
/// We override this method so that the action attribute is not emitted.
/// </summary>
protected override void RenderAttributes(HtmlTextWriter writer)
{
// write the form's name
writer.WriteAttribute("name", this.Name);
base.Attributes.Remove("name"); // write the form's method
writer.WriteAttribute("method", this.Method);
base.Attributes.Remove("method"); // remove the action attribute
base.Attributes.Remove("action"); // finally write all other attributes
this.Attributes.Render(writer); if (base.ID != null)
writer.WriteAttribute("id", base.ClientID);
} }
} 创建此类并对其进行编译之后,要在 ASP.NET Web 应用程序中使用它,应首先将其添加到 Web 应用程序的 References 文件夹中。然后,要 使用它来代替 HtmlForm 类,做法是在 ASP.NET 网页的顶部添加以下内容: <%@ Register TagPrefix="af" Namespace="ActionlessForm" Assembly="ActionlessForm" %>
Url地址重写的更多相关文章
- php url地址重写
地址重写: urlRewrite: 就是: 1. 将php的地址index.php不写只写Action模块和function方法, 或者 2. php地址转变成html地址, 就是一种假的html, ...
- Nginx 的编译安装和URL地址重写
本文转自:http://www.178linux.com/14119#rd?sukey=ecafc0a7cc4a741b573a095a3eb78af6b4c9116b74d0bbc9844d8fc5 ...
- Magento 自定义URL 地址重写 分类分级显示
我们打算将URL在分类页面和产品页面分别定义为: domain.com/category/分类名.html domain.com/category/子分类名.html domain.com/goods ...
- Apache Nginx URL 地址 重写
URL重写这东西在工作中用了很多次了,但每次都忘记了要记得把知道的积累下来. 哎,要么认为没必要,要么就是没时间?! 一.Apache 篇 官方地址:http://man.chinaunix.net/ ...
- springboot中url地址重写(urlwrite)
在日常网站访问中,会把动态地址改造成伪静态地址. 例如: 访问新闻栏目 /col/1/,这是原有地址,如果这样访问,不利于搜索引擎检索收录,同时安全性也不是很好. 改造之后: /col/1.html. ...
- URL地址重写例子(Helicon)
# Helicon ISAPI_Rewrite configuration file# Version 3.1.0.86 #RewriteEngine on RewriteRule ^/esf/.+( ...
- 【转载】ASP.NET MVC重写URL制作伪静态网页,URL地址以.html结尾
在搜索引擎优化领域,静态网页对于SEO的优化有着很大的好处,因此很多人就想把自己的网站的一些网页做成伪静态.我们现在在网络上发现很多博客网站.论坛网站.CMS内容管理系统等都有使用伪静态这一种情况,伪 ...
- 解决URL中包含“%2F”导致Apache地址重写mod_rewrite失效的问题
在使用Apache地址重写mod_rewrite期间,发现,当URL和PATH_INFO中出现%2f(/)或者%5c(\), 会被认为这是个不合法的请求, Apache将会直接返回"404 ...
- IIS:URL Rewrite实现vue的地址重写
vue-router 全局配置 const router = new VueRouter({ mode: 'history', routes: [...] }) URL Rewrite 1.添加规则 ...
随机推荐
- ipfs上传下载
上传下载步骤: 启动ipfs节点服务器: 页面效果显示如下: 当在一个终端启动ipfs节点服务器之后之后,上传下载步骤: 1.创建文件demo4,新建一个文件a.txt,文本内容为hello mkdi ...
- ORACL内部异常:
ORACL内部异常: ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 OR ...
- Confluence 6 管理应用服务器内存设置
应用服务器中的最小和最大 JVM Heap 空间配置将会影响系统的性能.Confluence 管理员可能希望对默认的配置进行修改,基于你系统的负载不同配置情况也会有所不同,请参考页面 Server H ...
- Confluence 6 恢复一个站点问题解决
如果你在导入的时候遇到了问题,检查下面的一些提示. 你的文件太大而不能上传?这个是非常常见的错误.出现的原因是备份文件不能在规定的时间内上传到服务器上.为了避免这个错误,放置你的导出文件到 < ...
- Confluence 6 选择一个外部数据库
注意: 选择一个合适的数据库通常需要花费很多时间.同时 Confluence 自带的 XML 数据备份和恢复功能通常也不适合合并和备份有大量数据的数据库.如果你想在系统运行后进行数据合并,你通常需要使 ...
- eclipse的安装及使用
1.安装 2工作区 3透视图添加透视图 关闭和显示各个子视图 点击视图右上角的关闭按钮可以关闭当前视图 可以选择Window-->Show View菜单项打开各个子视图 4创建项目 选择File ...
- C++ Primer 笔记——OOP
1.基类通常都应该定义一个虚析构函数,即使该函数不执行任何实际操作也是如此. 2.任何构造函数之外的非静态函数都可以是虚函数,关键字virtual只能出现在类内部的声明语句之前而不能用于类外部的函数定 ...
- const 和 const_cast
对于const变量,我们不能修改它的值,这是这个限定符最直接的表现.但是我们就是想违背它的限定希望修改其内容怎么办呢?下边的代码显然是达不到目的的: ; int modifier = constant ...
- c++实现 给定直角停车位两个点,求取剩余两点坐标。
//2018-09-08-fourmi /*************************include head files************************************ ...
- C# 属性(Property)和字段(Field)的区别
导读: 近期学习过程中发现了一些问题,我的学习只是学习,敲代码就是敲代码,没有加入思考,也不问为什么就直接去敲人家写好的例子去敲,把知识都学死了,逐渐散失了思考能力,所以学习的兴趣大打折扣,正如那句话 ...