怎样动态创建二级域名?

时间:2024-02-16 17:39:40


第一步:把域名设置成泛解析.
 就是把*.域名 解析到你的主机,是否支持泛解析,请查看你的域名商说明.
第二步:IIS设成的时候不要绑定域名.注意一台服务器里只能有一个站点不绑定域名
就是*.域名的默认访问页.
第三步:默认页里加入以下代码:关键部分如下:
string sURL=context.Request.ServerVariables["HTTP_HOST"].ToLower();
 sURL就是获取的域名部分 .
  xxx.域名
  对应的xxx就是用户名.然后查库里的记录,如xxx对应的是www.csd.net那就就把
它转向到www.csdn.net 或者写一个框架页隐藏直实域名

 

  第三步也可以写成HttpHandler或者HttpModule模块来处理
 HttpHandler模块:
public class DnsHttpHandler: IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
            string sUSER;
            UserDns user;
string userDomain=string.Empty;
string sURL=context.Request.ServerVariables["HTTP_HOST"].ToLower();
if(sURL.IndexOf("@")==-1&&sURL.IndexOf(".")==-1)
{
//判段域名,转向默认网址
context.Response.Redirect(DnsConfiguration.GetConfig().DefaultURL,true);
}

#region myhome设置
if(sURL=="保留域名")
{
context.Response.Redirect(DnsConfiguration.GetConfig().DefaultURL,true);
}
#endregion
#region 判段并获取用户名
sUSER=Utility.DomainToUser(sURL);
userDomain=Utility.GetFirstDomain(sURL);
//context.Response.Write(userDomain);
//context.Response.End();
user  =Users.GetUserDns(sUSER,userDomain);

if(user==null)
{
context.Response.Redirect(DnsConfiguration.GetConfig().DefaultURL,true);
}
          
         context.Response.Write( "<meta http-equiv=refresh content=\"0;url="+user.RedirectURL.Trim()+"\">");


#endregion

 

 

}

public bool IsReusable
{
get
{
return false;
}
}
}

 提取用户名模块:
public class Utility
{
public static string DomainToUser(string domain)
{
string username=string.Empty;
string[] first_name;
#region 判段并获取用户名

if(domain.IndexOf("@")==-1&&domain.IndexOf(".")==-1)
{
 return username;
}
if(domain.IndexOf(".")!=-1)
{
first_name=domain.Split( . );
if(first_name[0]=="www")
{
username=first_name[1];
}
else
{
username=first_name[0];
}
}
if(domain.IndexOf("@")!=-1)
{
first_name=domain.Split( @ );
if(first_name[0]=="www")
{
username=first_name[1];
}
else
{
username=first_name[0];
}
}
#endregion

 return username;
}

public static string GetFirstDomain(string domain)
{
 string[] first_name;
domain=domain.Replace( @ , . );
string temp=string.Empty;
if(domain.StartsWith("www."))
{
domain=domain.Replace("www.","");
}
if(domain.IndexOf( . )!=-1)
{
first_name=domain.Split( . );
}else
return string.Empty;
if(first_name.Length==2)
{
//sb.Append("{0}.{1}",first_name[0])
return String.Format("{0}.{1}",first_name[0],first_name[1]);
}
for(int i=1; i<first_name.Length;i++)
{
temp += first_name[i] + ".";
}
            temp=temp.Remove(temp.Length-1,1);
        return temp;
         
  
}
}

____________________________________________________________________________________
目前虚拟主机商提供将多个域名绑定到站点根目录,但是不提供类似cpanel那样可以将域名绑定到站点的子目录。
而当你手上有多个域名,网站空间和流量又有闲置的时候,是很希望
将这些资源利用起来,而且要做到降低做站的成本。而网络上流传的多域名绑到子目录多为判断HTTP_HOST再使用Asp的Response.Redirect或者php的header方法重订向到子目录去。这种方法在地址的请求上发生了变化,大家都知道Redirect的定向是很不友好的,在服务器端控制自动跳转会令访问者感到不安。
所以我需要的是对这个域名下面的所有请求都转接到对应的子目录里去
比如

http://www.xaradio.com/default.aspx
实际访问的是http://www.3pub.com/xaradio/default.aspx

http://www.xaradio.com/album.aspx?id=722
实际访问的是http://www.3pub.com/xaradio/album.aspx?id=722

http://www.xaradio.com/*.aspx
实际要访问到http://www.3pub.com/xaradio/*.aspx

而绑定到该站点根目录的其他域名和地址仍然不受影响
如: http://www.3pub.com/http://3pub.com/
 http://www.3pub.com/default.aspxhttp://3pub.com/default.aspx


http://www.aspxboy.com/484/default.aspx该文章详细的描述了在Asp.Net中使用HttpModule和HttpHander来重写Url,读懂他特别是http://www.aspxboy.com/484/archive.aspx#ekaa节将是我们下面工作的前提朋友们可以下载该文章附带的代码研究。

如果您对HttpModule的编成非常熟悉那么可以向下进行了

一。 先把配置文件从web.config内移出为了不让web.config变的非常臃肿,我们将配置文件从web.config内移出
假设我们的多域名绑定配置文件为“MulitDomain.config“
将RewriterConfiguration.cs的public static RewriterConfiguration GetConfig()方法
修改如下:


///
/// 从XML配置文件中返回重写信息
///
/// RewriterConfiguration
public static RewriterConfiguration GetConfig()
{
RewriterConfiguration config = (RewriterConfiguration) BoovooCache.Get(CacheKey);
if(config == null)
{
// 2005-08-18 wu meibo update the config file to SiteUrls.config
// HttpContext.Current.Cache.Insert("RewriterConfig", ConfigurationSettings.GetConfig("RewriterConfig"));

///************************************************************************************
/// 
/// 将配置文件移到单独的文件内,更新以下代码,原代码(上一行)停止工作
///
///************************************************************************************

string filePath = String.Empty;
if(HttpContext.Current != null)
{
filePath = HttpContext.Current.Server.MapPath("~/MulitDomain.config");
}
else
{
filePath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "MulitDomain.config";
}

XmlSerializer ser = new XmlSerializer(typeof(RewriterConfiguration));
FileStream fileReader = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
StreamReader reader = new StreamReader(fileReader);
config = (ser.Deserialize(reader)) as RewriterConfiguration;
reader.Close();
fileReader.Close();
if (File.Exists(filePath))
{
CacheDependency dep = new CacheDependency(filePath);
BoovooCache.Max(CacheKey,config,dep);
BoovooCache.ReSetFactor(config.CacheFactor);
}
}

return config;
} 二。做一些修补
RewriterModule.cs内

public virtual void Init(HttpApplication app)
{

///**********************************************************************************

:增加BeginRequest,在内增加防止黑客可能利用的某些Url漏洞攻击的代码
///**********************************************************************************

app.BeginRequest += new EventHandler(this.RewriterModule_BeginRequest);

// 警告!此代码不适用于 Windows 身份验证!
// 如果使用 Windows 身份验证,
// 请改为 app.BeginRequest

app.AuthorizeRequest += new EventHandler(this.RewriterModule_AuthorizeRequest);


} protected virtual void RewriterModule_BeginRequest(object o , EventArgs e)
{
HttpApplication app = ((HttpApplication)(o));
HttpServerUtility Server = app.Server;
HttpRequest Request = app.Request;

///************************************************************

/// 修补黑客可能采用".."的方法进入其他目录的问题
///************************************************************

string strURL = Server.UrlDecode(Request.RawUrl);
if (strURL.IndexOf("..") != -1)
{
throw new HttpException(404, "Not Found");
}

///**********************************************************************************

///***********************************************************************************

if (Request.Path.IndexOf(\'\\\') >= 0 ||
Path.GetFullPath(Request.PhysicalPath) != Request.PhysicalPath)
{
throw new HttpException(404, "Not Found");
}
} 三。开始匹配域名

protected void Rewrite(string requestedPath, System.Web.HttpApplication app)
{
string host = app.Context.Request.Url.Host.ToString().ToLower();

app.Context.Trace.Write("RewriterModule", "Entering ModuleRewriter");  
RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules;
for(int i = 0; i < rules.Count; i++)
{//将MulitDomain.config内定义的规则LookFor的值逐个匹配当前主机名判断否被定义了需要重写
//如果匹配则需要重写,那将请求重写到SendTo定义的目录内的该文件
string lookFor = "^" + rules[i].LookFor + "$";
//string lookFor = "^" + Rewriter.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor + requestedPath) + "$";
Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);
if (re.IsMatch(host))
{
string sendToUrl = Rewriter.ResolveUrl(app.Context.Request.ApplicationPath,  rules[i].SendTo + requestedPath);
app.Context.Trace.Write("RewriterModule", "Rewriting URL to " + sendToUrl);
Rewriter.RewriteUrl(app.Context, sendToUrl);
break;
}
}
app.Context.Trace.Write("RewriterModule", "Exiting ModuleRewriter");
}
四。写规则文件
MulitDomain.config的匹配规则如下:

<?xml version="1.0" encoding="utf-8" ?>
 <RewriterConfig>
 <Rules>
  <RewriterRule>
   <LookFor>www\.xaradio\.com</LookFor>
   <SendTo>~/xaradio</SendTo>
  </RewriterRule>
  <RewriterRule>
   <LookFor>xaradio\.com</LookFor>
   <SendTo>~/xaradio</SendTo>
  </RewriterRule>
 </Rules>
  </RewriterConfig>
最后说明一下,根目录下一定要有一个Default.aspx如果你的所有域名都按照这种方式“绑定”那么根目录下放置一个空Default.aspx就可以,该文件来“欺骗IIS” ,防止直接使用域名访问的时候IIS查找不到default或者index文件就报404错误,等到该检查过去之后权利已经移交到aspnet_isapi.dll那里了。
______________________________________________________________________________________
大家应该知道,微软的URLRewrite能够对URL进行重写,但是也只能对域名之后的部分进行重写,而不能对域名进行重写,如:可将 http://www.abc.com/1234/  重写为 http://www.abc.com/show.aspx?id=1234  但不能将
http://1234.abc.com  重写为  http://www.abc.com/show.aspx?id=1234

要实现这个功能,前提条件就是  www.abc.com 是泛解析的,再就是要修改一下URLRewriter了。
总共要修改2个文件
1.BaseModuleRewriter.cs

protected virtual void BaseModuleRewriter_AuthorizeRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication) sender;
            Rewrite(app.Request.Path, app);
        }
改为

protected virtual void BaseModuleRewriter_AuthorizeRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication) sender;
            Rewrite(app.Request.Url.AbsoluteUri, app);
        }

就是将  app.Request.Path 替换成了  app.Request.Url.AbsoluteUri

2.ModuleRewriter.cs

for(int i = 0; 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].LookFor) + "$";
 
                // Create a regex (note that IgnoreCase is set)
                Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);
 
                // See if a match is found
                if (re.IsMatch(requestedPath))
                {
                    // match found - do any replacement needed
                    string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
 
                    // log rewriting information to the Trace object
                    app.Context.Trace.Write("ModuleRewriter", "Rewriting URL to " + sendToUrl);
 
                    // Rewrite the URL
                    RewriterUtils.RewriteUrl(app.Context, sendToUrl);
                    break;        // exit the for loop
                }
            }
改为

for(int i = 0; i < rules.Count; i++)
            {
                // get the pattern to look for, and Resolve the Url (convert ~ into the appropriate directory)
                string lookFor = "^" + rules[i].LookFor + "$";
 
                // Create a regex (note that IgnoreCase is set)
                Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);
 
                // See if a match is found
                if (re.IsMatch(requestedPath))
                {
                    // match found - do any replacement needed
                    string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
 
                    // log rewriting information to the Trace object
                    app.Context.Trace.Write("ModuleRewriter", "Rewriting URL to " + sendToUrl);
 
                    // Rewrite the URL
                    RewriterUtils.RewriteUrl(app.Context, sendToUrl);
                    break;        // exit the for loop
                }
            }

string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor) + "$";

改成了

string lookFor = "^" + rules[i].LookFor + "$";


完成这2处改动之后重新编译项目,将生成的dll复制到bin目录下。

再就是写web.config里的重写正则了

<RewriterRule>
            <LookFor>http://(\d+)\.abc\.com</LookFor>
            <SendTo>/show.aspx?id=$1</SendTo>
        </RewriterRule>

好了大功告成,你在IE地址栏输入http://1234.abc.com,就可以看到http://www.abc.com/show.aspx?id=1234

的结果了 若你在实际应用中碰到了问题,请查看文章 "修改UrlRewrite以对域名进行重写"需要注意的问题 ,希望能够帮助你!
_______________________________________________________________________________________________