Asp.net mvc ASP.NET MVC:从控制器返回CDN映像

Asp.net mvc ASP.NET MVC:从控制器返回CDN映像,asp.net-mvc,image,cdn,Asp.net Mvc,Image,Cdn,我知道如何从MVC控制器返回图像,但想知道从MVC控制器返回CDN中的图像是否会破坏使用CDN进行图像处理的目的。使用以下代码是否会导致托管web应用程序的web服务器从CDN下载,然后让用户可以从web服务器下载?映像是否下载了两次,一次从CDN下载到Web服务器,然后从Web服务器下载到用户?如果是这样,那比直接在Web服务器上托管图像更糟糕?或者该映像只下载一次,直接从CDN下载给最终用户 如何从MVC控制器返回映像,同时利用CDN public ActionResult Thum

我知道如何从MVC控制器返回图像,但想知道从MVC控制器返回CDN中的图像是否会破坏使用CDN进行图像处理的目的。使用以下代码是否会导致托管web应用程序的web服务器从CDN下载,然后让用户可以从web服务器下载?映像是否下载了两次,一次从CDN下载到Web服务器,然后从Web服务器下载到用户?如果是这样,那比直接在Web服务器上托管图像更糟糕?或者该映像只下载一次,直接从CDN下载给最终用户

如何从MVC控制器返回映像,同时利用CDN

    public ActionResult Thumb(int id)
    {
        //process 
        var file = Server.MapPath(" path to image in the CDN ");
        //do your stuff
        return File(file, "image/jpg", Path.GetFileName(file));
    }

在控制器操作中,您需要执行HTTP请求以从远程服务器获取映像:

public ActionResult Thumb(int id)
{
    using (var client = new WebClient())
    {
        byte[] image = client.DownloadData("http://cdn.foo.com/myimage.jpg");
        return File(image, "image/jpg");
    }
}
然后:

<img src="@Url.Action("Thumb")" alt="" />

显然,现在图像被下载了两次。一次从CDN进入控制器,一次从客户端进入。这完全违背了控制器操作的目的,您可以直接从CDN引用映像:

<img src="http://cdn.foo.com/myimage.jpg" alt="" />

这显然是假设客户机可以访问CDN


当然,如果您的控制器操作不仅仅是从CDN获取图像并将其流式传输到客户端,例如从CDN获取图像并调整其大小,那么您肯定应该采取第一种方法。

Server.MapPath用于映射图像的物理路径,它对CDN图像没有任何作用,因为它不存在于物理路径的本地。不,您不想返回文件

您的HTML只需在
不要从控制器返回实际图像。更糟糕的是,您需要下载两次(CDN->server->client)。您根本不需要
拇指
操作

如果需要在控制器中生成到CDN上文件的链接,那么只需向视图的CDN链接模型添加属性并将其设置在控制器中

在控制器中创建链接:

<img src="http://mycdn.com/image" />
然后最后在你的视图中设置它

public ActionController SomeAction(int id){
   var model = new SomeActionViewModel();

   model.CDNLink = // do some stuff to generate CDN Link and set them on the model;
   return View(model);
}

我使用URL重写模块2.0外围规则。 更改响应html Img(图像)、链接(css)、脚本(js)标记url

电流响应

<img src="@Model.CDNLink" alt=""/>
。。。
...
设置web.config URL重写配置

...
<img src="/images/photo1.jpg" />
<img src="/images/photo2.jpg" />
...

重写响应

<rewrite>
    <outboundRules>
        <rule name="cdn" preCondition="html" enabled="true">
            <match filterByTags="Img, Link, Script" 
                        pattern="^/(images|csc|js)/(.*)" />
            <action type="Rewrite" value="//cdn.local/{R:1}/{R:2}" />
        </rule>
        <preConditions>
            <preCondition name="html">
                <add input="{RESPONSE_CONTENT_TYPE}" pattern="text/html" />
            </preCondition>
        </preConditions>
    </outboundRules>
</rewrite>
。。。
...

希望获得帮助。

CDN配置可能会有所不同,但最常见的设置是CDN服务器将充当服务器的大型分布式代理(“源服务器”)

CDN不关心您如何交付内容。您可以告诉它通过URL、内容类型或其他因素代理内容

因此,假设内容从控制器交付后不会改变,您的情况可以设置如下:

  • 对CDN服务器的请求
  • CDN服务器对源服务器上控制器方法的请求
  • 控制器方法生成内容
  • CDN为后续请求缓存内容
  • CDN返回内容
  • 通过URL对相同内容的后续请求从CDN返回
  • 通常,返回静态内容时最重要的因素是您使用的URL结构

    CDN在缓存和过期方面确实(可以)关心响应头,但如果您能够正确地调整URL以按URL提供唯一内容(例如,解决版本控制问题),则最好避免这种情况


    如果您试图保护内容的安全,也可以使用CDN,但通常需要CDN特定的技术。

    假设您需要先进行一些计算以确定资源,例如根据某个ID进行查找,以解析CDN url。您绝对不应该使用web客户端并将映像下载到字节数组中。如果你必须下载文件,它本质上变成了一个易失性资源,你需要决定如何处理它,使用断路器,可能没有缓存,你需要对它进行缓冲,这样它就不会占用太多内存

    在本例中,您最好解析url,并根据用例使用重定向301/302

    ...
    <img src="//cdn.local/images/photo1.jpg" />
    <img src="//cdn.local/images/photo2.jpg" />
    ...
    

    这确实无法达到目的,但如果客户端浏览器试图从根url获取favicon,但favicon是不在根中的动态url,那么我们必须从cdn获取它。
    public ActionResult Thumb(int id)
    {
        //resolve url
        var file = " path to image in the CDN ";
        //redirect permanent
        return RedirectPermanent(file);
        //OR redirect 
        return Redirect(file);
    }