2011-07-31 15 views
8

Necesito usar CDN para todas las imágenes de mi sitio. Por lo tanto, he decidido usar el módulo de reescritura de IIS de IIS, , porque edito manualmente todas las vistas de mi sitio, es imposible para mí.Poner imágenes en CDN, utilizando MVC3 en IIS7

Así que he hecho reglas para IIS, por ejemplo:

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

Su trabajadas, pero como se puede ver que hay redirigir tipo se utiliza (301 Permanente). Y creo que esto afecta el rendimiento del sitio. Quizás es posible editar Request.Output para reemplazar la imagen URL?

Consejos, ¿cómo puedo usar CDN para imágenes, no edito mis vistas y evito redirecciones?

Cualquier ayuda será apreciada

Respuesta

7

Estoy de acuerdo con Steve. Tiene el reescritor de URL haciendo 301 redirecciones, pero para cada imagen que necesita la página, el navegador aún hace una solicitud al servidor primero para descubrir que se lo redirecciona 301 a una URL de CDN. Lo único que está ahorrando en este punto es la descarga del contenido.

En lugar de hacer eso, puede colocar un filtro de respuesta que modificará las URL de los activos antes de enviar la respuesta al navegador del cliente. De esta manera, el navegador del cliente no tiene que realizar ninguna llamada a su servidor para los activos estáticos:

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

y luego la 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 
    } 
} 

El resultado de esto es que todos los activos de contenido que se parecen <img src="\Content\whatever.jpg" /> se convertirá en <img src="cdn-url.com\Content\whatever.jpg" />

+0

esto es exactamente lo que necesito, gracias usted y @Steve! – bogert

+0

¿Puedo preguntar, dónde deberíamos poner este filtro de respuesta en la aplicación ASP MVC? – DevMania

+0

¿La clase de filtro de respuesta real? La clase puede residir en cualquier parte del proyecto, siempre que el controlador tenga acceso a la clase. –

1

Teniendo en cuenta que las URL originales provienen de su contenido y no, por ejemplo, de favoritos, creo que tendrá problemas para evitar una solicitud a su sitio y una redirección; un impacto de rendimiento potencialmente significativo que podría anular los beneficios de usar un CDN.

Sería mejor si su podría aplicar la reescritura de URL a la que se transmite HTML al navegador, en lugar de cuando llega una petición.

El problema es que no sé cómo (a menos que esté usando el servidor ISA, en cuyo caso podría decírtelo, pero sospecho que no lo eres).

Puede crear un ActionFilter personalizado y anular OnResultExecuted, pero debe anotar su controlador con el atributo de filtro.

+0

En cuanto a OnResultExecuted: ¿es posible editar outgouing html? No puedo entenderlo y google no quiere ayudarme – bogert

+0

@ Mike tiene lo que yo estaba buscando - es un filtro de respuesta ASP.NET que queremos, no un MVC ... –

Cuestiones relacionadas