【问题标题】:.Net MVC bundling/minificiation - CDN friendly file naming.Net MVC 捆绑/缩小 - CDN 友好的文件命名
【发布时间】:2013-05-05 05:30:39
【问题描述】:

我正在使用 .Net MVC 捆绑和缩小。它可以很好地完成这项工作,只是你最终会得到一个如下所示的网址:

/bundles/AllMyScripts?v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81

该项目将在 AWS Cloudfront 中有静态文件,默认情况下它不喜欢查询字符串。可以对其进行更改以支持此功能,但会降低性能。

可以将捆绑配置为将令牌放入文件名而不是查询字符串中吗?我也愿意使用 Web Grease 以外的其他东西。

【问题讨论】:

  • 我可能不在,但我不确定其中一个与另一个有什么关系? MVC 捆绑将收集要捆绑的文件,捆绑它们并从 Web 服务器返回它们,而不是从实际的 CDN 中返回。据我所知,您不能将捆绑包存储在您的网络应用程序之外(如果可以,那将是很棒的,请纠正我)。如果您希望压缩文件位于 Web 应用程序之外,我认为您需要手动压缩您的项目。
  • @Tommy 如果缓存中没有源,CDN 会从源中提取。请求cdn.mysite.com/content/css/min.css 将发送到 CDN,但它不存在,CDN 会从源请求此请求 - 这就是 .net 发挥作用的地方。您不会推送到 CDN,它会从您那里拉取。
  • 哦,我明白你现在在问什么了,我在相反的文件流方向上查看你的问题。我的错。我以为你问的是捆绑过程的实际拉动,而不是分发捆绑包的 CDN。

标签: .net asp.net-mvc bundling-and-minification


【解决方案1】:

您可以使用 MapRouteController 将捆绑 URL 重写为对 CDN 友好。

而不是 /bundles/AllMyScripts?v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81 你将拥有CDN_Bundle/bundles/AllMyScripts/r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81

路线图:

    routes.MapRoute(
            name: "CDN_Bundle",
            url: "CDN_Bundle/{*virtualPath}",
            defaults: new { controller = "CDN_Bundle", action = "Index" }

行动:

    public ActionResult Index(string virtualPath)
    {
        virtualPath = virtualPath.Trim('/');
        int lastSlash = virtualPath.LastIndexOf("/");
        string hashCode = virtualPath.Substring(lastSlash + 1, virtualPath.Length - lastSlash -1 );
        virtualPath = virtualPath.Substring(0, virtualPath.LastIndexOf("/"));

        WebClient webClient = new WebClient();
        webClient.Headers.Add("user-agent", Request.UserAgent);
        Stream data = webClient.OpenRead(Request.Url.GetLeftPart(UriPartial.Authority) + Path.Combine(Request.ApplicationPath, virtualPath) + "?v=" + hashCode);
        StreamReader reader = new StreamReader(data);
        string content = reader.ReadToEnd();

        return Content(content);
    }

用这个代替Scripts.Render

         <script src="/cdn_bundle@(System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/AllMyScripts").Replace("?v=","/"))"></script>

【讨论】:

  • 这是个好主意,但必须有更有效的方法!
  • @ScottE 有效的方法是由 WG 手动缩小脚本并将它们放在 AWS CloudFront 上,然后将它们捆绑并将捆绑的 UseCdn 属性设置为 true。请参阅Amazon CloudFront,请参阅在Bundling and Minification 中使用 CDN
  • 我更喜欢这个建议。你能更详细地解释一下这个建议吗?
  • @ScottE 我之前的评论中有两个链接是关于使用“UseCdn”属性以及如何将静态文件添加到 Amazon CloudFront。但我不明白为什么你认为我的方法无效。正如您在评论中提到的,CDN 仅在缓存中没有对象时才请求该对象。因此,该操作被调用一次,这里没有性能问题。
  • 感谢@Kambiz 的建议,但我走了一点不同的方向。但是,我确实使用了 System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl。此外,关于 CDN,这是一个公平的观点——一旦被缓存,例程将不会受到影响,直到它被更改/陈旧。
【解决方案2】:

不确定我是否正确地接受了你之后的内容,但是..

当你在 BundelConfig 中定义 bundle 时,ScriptBundle 中有一个名为 CdnPath 的参数,可以为每个 bundel 设置一个 CDN 位置。

在注册包中

Dim bundel As New ScriptBundle("~/bundles/myfoo")
bundel.CdnPath = "http://foo.com/foo.js"

bundles.UseCdn = True

【讨论】:

    【解决方案3】:

    好的,我想出了一个不错的解决方案,涉及 url 重写和自定义 html 帮助器。

    web.config:

      <rule name="BundlingRewrite" stopProcessing="true">
          <match url="^content/min/([^/]+)/([^/]+)/?$" />
          <conditions>
              <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
              <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="content/min/{R:1}?v={R:2}" />
      </rule>
    

    帮手:

    public static IHtmlString RenderCdnCss(this HtmlHelper helper, params string[] paths)
    {
        if (BundleTable.EnableOptimizations)
        {
            StringBuilder sb = new StringBuilder();
            Uri baseUri = helper.ViewContext.HttpContext.Request.Url;
    
            foreach (string s in paths) {
                Uri uri = new Uri(baseUri, BundleTable.Bundles.ResolveBundleUrl(s));
                sb.AppendFormat("<link href=\"{0}\" rel=\"stylesheet\"/>", uri.PathAndQuery.Replace("?v=", "/"));                    
            }
            return new HtmlString(sb.ToString());
        }
        return Styles.Render(paths);
    }
    

    帮助程序将捆绑的 url 翻译成对 CDN 更友好的内容。例如:

    /content/min/css?v=3GWBEyScjC610oPQm0JVybboQ_EmX3StAuCZjd_B7bE1

    变成

    /content/min/css/3GWBEyScjC610oPQm0JVybboQ_EmX3StAuCZjd_B7bE1

    url 重写 (IIS Url Rewrite 2.0) 在 content/min/{some folder}/{some token} 中查找 url 并将其重写为 content/min/{some folder}?v={some token} (默认情况下路径的外观)

    因此,捆绑器并不明智,并且路径变得对 CDN 友好。在我的情况下,我还将 cdn url 附加到 url 的前面,但这不包括在上面。

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 2014-05-22
      • 2014-11-26
      • 1970-01-01
      • 2018-05-11
      • 1970-01-01
      • 1970-01-01
      • 2013-09-11
      • 2012-08-16
      相关资源
      最近更新 更多