Поместите образы в CDN, используя MVC3 на IIS7 - PullRequest
8 голосов
/ 01 августа 2011

Мне нужно использовать CDN для всех изображений на моем сайте.Итак, я решил использовать модуль IIS Url-rewriting, потому что редактировать вручную все виды моего сайта - для меня это невозможно.

Поэтому я создал правила для 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 постоянный).И я думаю, что это влияет на производительность сайта.Может быть, есть возможность отредактировать Request.Output для замены URL изображения?

Пожалуйста, посоветуйте, как я могу использовать CDN для изображений, не редактировать мои представления и избегать перенаправлений?

Любая помощь будет оценена

Ответы [ 2 ]

7 голосов
/ 01 августа 2011

Я согласен со Стивом.У вас есть программа перезаписи URL, которая выполняет перенаправление 301, но для каждого изображения, которое требуется странице, браузер все еще сначала запрашивает сервер, чтобы определить, что он перенаправлен на 301 на URL CDN.Единственное, что вы сохраняете в данный момент, - это загрузка контента.

Вместо этого вы можете просто установить фильтр ответов, который будет изменять 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
    }
}

В результате все содержимоеактивы, которые выглядят как <img src="\Content\whatever.jpg" />, будут конвертированы в <img src="cdn-url.com\Content\whatever.jpg" />

1 голос
/ 01 августа 2011

Учитывая, что исходные URL-адреса исходят от вашего контента, а не, например, от закладок, я думаю, у вас возникнут проблемы с отказом от запроса на ваш сайт и перенаправления;потенциально значительное влияние на производительность, которое может свести на нет преимущества использования CDN.

Было бы лучше, если бы вы могли применить перезапись URL-адреса к HTML, который передается в браузер, а не при поступлении запроса.

Проблема в том, что я не знаю, как (если вы не используете ISA-сервер, в таком случае я мог бы сказать вам, но я подозреваю, что вы не)!

Вы можете создатьПользовательский ActionFilter и переопределить OnResultExecuted, но вам необходимо аннотировать ваш контроллер с помощью атрибута фильтра.

...