2011-07-31 11 views
8

Potrzebuję użyć CDN dla wszystkich obrazów w mojej witrynie. Tak więc, zdecydowałem się użyć modułu do przepisywania adresów URL IIS, , ponieważ edytuję ręcznie wszystkie moje widoki strony - jest to niemożliwe dla mnie.Umieść obrazy na CDN, używając MVC3 na IIS7

Tak Ive wykonane zasady IIS, np:

<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> 

Jego działało, ale jak widać nie ma przekierować typ jest używany (301 Permanent). I myślę, że ma to wpływ na wydajność witryny. Być może jest możliwa edycja Request.Output w celu zastąpienia adresu URL obrazu?

Proszę wskazać, w jaki sposób mogę użyć CDN do zdjęć, nie edytuj moich widoków i unikaj przekierowań?

Każda pomoc będzie mile widziane

Odpowiedz

7

Zgadzam się ze Stevem. Masz przeszukiwarkę adresów URL wykonującą przekierowania 301, ale dla każdego obrazu, którego strona potrzebuje, przeglądarka wciąż wysyła najpierw żądanie do serwera, aby odkryć, że przekierowano 301 do URL-a CDN. Jedyną rzeczą, którą oszczędzasz w tym momencie, jest pobranie treści.

Zamiast tego można po prostu wstawić filtr odpowiedzi, który zmodyfikuje adresy URL zasobów przed wysłaniem odpowiedzi do przeglądarki klienta. W ten sposób nigdy przeglądarka klient musi dokonywać żadnych połączeń do serwera na aktywa statycznych:

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

a następnie 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 
    } 
} 

Wynikiem tego jest to, że wszystkie aktywa treści, które wyglądają jak <img src="\Content\whatever.jpg" /> zostanie przekonwertowany na <img src="cdn-url.com\Content\whatever.jpg" />

+0

to jest dokładnie to, czego potrzebuję, dziękuję Ty i @Steve! – bogert

+0

Czy mogę zapytać, gdzie powinniśmy umieścić ten filtr odpowiedzi w aplikacji ASP MVC? – DevMania

+0

Właściwa klasa Filter Response? Klasa może znajdować się w dowolnym miejscu w projekcie, o ile kontroler ma dostęp do klasy. –

1

Biorąc pod uwagę, że pierwotne adresy URL pochodzą z treścią, a nie, na przykład, z zakładek, myślę, że masz problemy z uniknięciem wniosek do swojej strony i przekierowanie; potencjalnie znaczący wpływ na wydajność, który mógłby negować korzyści wynikające z używania CDN.

Byłoby lepiej, jeśli może mieć zastosowanie do przepisywania URL HTML, który jest przesyłany do przeglądarki, zamiast gdy nadejdzie żądanie.

Kłopot w tym, że nie wiem jak (chyba, że ​​jesteś używając serwera ISA, w takim przypadku mógłbym ci powiedzieć, ale podejrzewam, że nie jesteś)!

Można utworzyć niestandardowy ActionFilter i zastąpić OnResultExecuted, ale trzeba dodać adnotację do kontrolera z atrybutem filtru.

+0

Jeśli chodzi o OnResultExecuted: czy możliwe jest edytowanie outgouing html? Nie mogę tego rozgryźć, a Google nie chce mi pomóc – bogert

+0

@ Mike ma to czego szukałem - to filtr odpowiedzi ASP.NET, którego chcemy, a nie MVC ... –

Powiązane problemy