zoukankan      html  css  js  c++  java
  • 使用http module 对url进行重写的尝试

      因为一些原因,要将原来两个独立的站点(假设为dh.site.com和cd.site.com)放到同一个站点的两个application下,分别为(www.site.com/dh和www.site.com/cd)。

      因为在开发的时候,大部分静态文件的引用路径都是采用绝对路径的形式,例如/style/css1.css。可想而知,当将两个站点作为两个application放置后,这些静态文件就变得无法访问了,因为文件真实的路径已经变成了/dh/style.css1.css了。解决这个问题的最直接的方法就是修改所有的绝对路径:要么将原来的路径加上application的虚拟根路径(例如将/style.css1.css变成/dh/style.css1.css),要么改成相对路径。但无论如何,直接修改路径的方式都要找出散布在各个角落里的路径查找出来,再进行修改。虽然利用IDE的查找替换功能可以很快将路径查找出来,但也难免查找不完全,另一方面,如果路径数量非常多,则不得不花费大量时间去修改并且在修改后进行检查排错。

      尝试一:使用http module进行路径重写。

        这也是非常直接地联想到的方法:使用http module(可以使用url rewriter,或者自己编写一个http module)对正在进行访问的url进行重写到正确的路径。但这使用http module进行重写会有一个问题:只能用作重写静态文件请求,而对于aspx之类的动态文件的请求,因为在IIS6或以上,不同应用程序运行在不同的应用程序域(app domain)中,因此对动态文件的请求进行重写转跳,会发现两个转跳对象的session根本不同,或者根本不能加载类型(root application可以加载子application的类型)。这无论从网站安全角度,还是程序都安全角度来说,都是合理的。

      因为这里需要自定义更多的东西,因此需要自己编写一个http module,而不是使用url rewriter。思路如下:因为cd和dh中的静态文件都是指向到虚拟根目录的,因此需要在站点的root application中使用该http module。而在http module中,根据静态文件请求的referrer来判断请求时来自dh还是cd,然后再重定向到dh或者cd下相对应的文件。

      http module中的代码:

    public class RedirectModule : IHttpModule
        {
            //定义静态文件的扩展名数组
            static string[] staticsFilesExName=new string[]{".jpg",".jepg",".gif",".png",".css",".html",".js"};
            void context_BeginRequest(object sender, EventArgs e)
            {
                HttpApplication app = sender as HttpApplication;
                if (app.Context.Request.UrlReferrer != null)
                {
                    //取得页面的referrer,进行判断请求是来自www.site.com/dh还是来自www.site.com/cd
                    string referrer = app.Context.Request.UrlReferrer.AbsoluteUri;
    
                    //取得application root path部分,也就是http://www.site.com/dh中的"/dh"部分
                    string appRootPath = referrer.Substring(23, 3);
    
                    string rawUrl = app.Request.RawUrl;
                    //得到转跳的url
                    string reUrl = appRootPath + rawUrl;
    
                    string extendName = app.Request.Path.Substring(app.Request.Path.LastIndexOf("."));
    
                    //判断请求的对象是否为静态文件,是则转跳。
                    if (RedirectModule.staticsFilesExName.Contains(extendName.ToLower()))
                    {
                        app.Context.RewritePath(reUrl);
                    }
                }
            }
    
            public void Dispose()
            {
                
            }
            public void Init(HttpApplication context)
            {
                context.BeginRequest += new EventHandler(context_BeginRequest);
            }
        }

      注:在IIS7.5中,为了能使http module正常工作,除了在web.config/httpModules节下添加http module外,必须将站点的应用程序池版本.net framework版本设置为V2.0,并且将托管管道模式设置经典(classic),此外,还可能需要在system.webServer/handlers节中添加配置:

    <add name="wildcard" path="*" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="None" preCondition="classicMode,runtimeVersionv2.0,bitness32" />

      然而,虽然使用http module能解决静态文件访问的问题,但不能重写动态文件,所以这不是个完美的解决方案。当然,如果动态文件的url数量少,手动改起来工作也不大的话,这也是个可以接受的方法。

      另外,可以考虑一下使用isapi filter来实现请求url重写,而且因为不同于http module要受到.net的限制,isapi filter运行在IIS层次之中,是否能突破应用程序池的限制,重定向的文件能顺利被执行(就如同该请求事来自浏览器一样)?

  • 相关阅读:
    2017.4.18下午
    2017.4.18上午
    2017.4.17上午
    2017.4.14下午
    2017.4.14上午
    4.17下午
    4.17上午
    4.13下午
    4.13上午
    4.10上午
  • 原文地址:https://www.cnblogs.com/lwhkdash/p/2855679.html
Copyright © 2011-2022 走看看