1

我正在使用 .Net MVC 捆绑和缩小。它做得很好,除了你最终得到一个如下所示的网址:

/bundles/AllMyScripts?v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81

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

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

4

3 回答 3

1

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

网络配置:

  <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 的前面,但这不包括在上面。

于 2013-05-15T19:00:30.947 回答
0

您可以使用 aMapRoute和 aController将捆绑 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>
于 2013-05-14T05:38:22.333 回答
0

不知道我是否正确地拿起了你的东西,但是..

当您在 BundelConfig 中定义捆绑包时,ScriptBundle 有一个名为 CdnPath 的参数,可以为每个捆绑包设置一个 CDN 位置。

在注册包中

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

bundles.UseCdn = True
于 2013-05-15T14:07:13.330 回答