我正在使用 .Net MVC 捆绑和缩小。它做得很好,除了你最终得到一个如下所示的网址:
/bundles/AllMyScripts?v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81
该项目将在 AWS Cloudfront 中有静态文件,默认情况下它不喜欢查询字符串。可以对其进行更改以支持此功能,但会降低性能。
可以将捆绑配置为将令牌放入文件名而不是查询字符串中吗?我也愿意使用 Web Grease 以外的东西。
我正在使用 .Net MVC 捆绑和缩小。它做得很好,除了你最终得到一个如下所示的网址:
/bundles/AllMyScripts?v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81
该项目将在 AWS Cloudfront 中有静态文件,默认情况下它不喜欢查询字符串。可以对其进行更改以支持此功能,但会降低性能。
可以将捆绑配置为将令牌放入文件名而不是查询字符串中吗?我也愿意使用 Web Grease 以外的东西。
好的,我想出了一个不错的解决方案,涉及 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 的前面,但这不包括在上面。
您可以使用 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>
不知道我是否正确地拿起了你的东西,但是..
当您在 BundelConfig 中定义捆绑包时,ScriptBundle 有一个名为 CdnPath 的参数,可以为每个捆绑包设置一个 CDN 位置。
在注册包中
Dim bundel As New ScriptBundle("~/bundles/myfoo")
bundel.CdnPath = "http://foo.com/foo.js"
bundles.UseCdn = True