【问题标题】:Put images on CDN, using MVC3 on IIS7将图像放在 CDN 上,在 IIS7 上使用 MVC3
【发布时间】:2011-10-17 02:01:42
【问题描述】:

我需要为我网站上的所有图片使用 CDN。 所以,我决定使用 IIS Url 重写模块, 因为手动编辑我所有的网站视图 - 这对我来说是不可能的。

所以我为 IIS 制定了规则,例如:

<rule name="cdn1" stopProcessing="true">

   <match url="^Content/Images.*/(.*\.(png|jpeg|jpg|gif))$" />

   <action 
      type="Redirect" 
      url="http://c200001.r9.cf1.rackcdn.com/{ToLower:{R:1}}" 
      redirectType="Permanent" />

</rule>

它有效,但正如您所见,使用了重定向类型(301 Permanent)。 而且我认为它会影响网站性能。 也许可以编辑 Request.Output 来替换图片 URL?

请指教,我怎样才能将 CDN 用于图像,不要编辑我的视图并避免重定向?

任何帮助将不胜感激

【问题讨论】:

    标签: asp.net-mvc-3 iis-7 url-rewriting cdn url-rewrite-module


    【解决方案1】:

    我同意史蒂夫的观点。您让 URL 重写器执行 301 重定向,但是对于页面需要的每个图像,浏览器仍然首先向服务器发出请求,以发现它是 301 重定向到 CDN Url。此时您唯一要保存的是内容的下载。

    您可以放置​​一个响应过滤器,在将响应发送到客户端浏览器之前修改资产的 URL,而不是这样做。这样一来,客户端浏览器就不必对您的服务器进行任何调用以获取静态资源:

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.RequestContext.HttpContext.Response.Filter = new CdnResponseFilter(filterContext.RequestContext.HttpContext.Response.Filter);
    }
    

    然后是 CdnResponseFilter:

    public class CdnResponseFilter : MemoryStream
    {
        private Stream Stream { get; set; }
    
        public CdnResponseFilter(Stream stream)
        {
            Stream = stream;
        }
    
        public override void Write(byte[] buffer, int offset, int count)
        {
            var data = new byte[count];
            Buffer.BlockCopy(buffer, offset, data, 0, count);
            string html = Encoding.Default.GetString(buffer);
    
            html = Regex.Replace(html, "src=\"/Content/([^\"]+)\"", FixUrl, RegexOptions.IgnoreCase);
            html = Regex.Replace(html, "href=\"/Content/([^\"]+)\"", FixUrl, RegexOptions.IgnoreCase);              
    
            byte[] outData = Encoding.Default.GetBytes(html);
            Stream.Write(outData, 0, outData.GetLength(0));
        }
    
        private static string FixUrl(Match match)
        {
            //However the Url should be replaced
        }
    }
    

    这样做的结果是所有看起来像&lt;img src="\Content\whatever.jpg" /&gt; 的内容资产都将转换为&lt;img src="cdn-url.com\Content\whatever.jpg" /&gt;

    【讨论】:

    • 请问,我们应该把这个响应过滤器放在 ASP MVC 应用程序的什么地方?
    • 实际的响应过滤器类?只要控制器有权访问该类,该类就可以驻留在项目中的任何位置。
    • 谢谢,我的意思是如何在asp MVC中使用,在哪里注入?
    • OnActionExecuted 方法,您可以在控制器类中覆盖该方法。上面答案中的第一个代码 sn-p 显示了您注入过滤器的位置。
    • 考虑用这一行替换 2 行正则表达式。它更健壮一点。 html = Regex.Replace(html, "([href|src]=[\"'])(/Content/[^\"']+)", "$1" + GetCdnEndPoint() + "$2", RegexOptions.忽略大小写);
    【解决方案2】:

    鉴于原始 URL 来自您的内容,而不是例如来自书签,我认为您将难以避免对您网站的请求和重定向;潜在的重大性能影响,可能会抵消使用 CDN 的好处。

    如果您可以将 URL 重写应用于传输到浏览器的 HTML,而不是在请求到来时进行,那会更好。

    麻烦的是,我不知道怎么做(除非你使用的是 ISA 服务器,在这种情况下我可以告诉你,但我怀疑你不是)!

    您可以创建自定义 ActionFilter 并覆盖 OnResultExecuted,但您需要使用 filter 属性注释控制器。

    【讨论】:

    • 关于 OnResultExecuted:是否可以编辑 outgouing html?想不通,谷歌不想帮助我
    • @Mike 得到了我想要的东西 - 它是我们想要的 ASP.NET 响应过滤器,而不是 MVC 过滤器...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 2021-07-21
    • 2020-11-15
    • 2011-02-24
    • 2014-07-01
    • 2016-06-20
    相关资源
    最近更新 更多