Использование ASP.NET 4.5 Bundling и CDN (например, CloudFront)
ASP.NET 4.5 имеет отличную новую функцию связывания и, похоже, имеет определенную поддержку для использования CDN. Пример, предоставленный Microsoft для использования функции связывания с CDN, - это
public static void RegisterBundles(BundleCollection bundles)
{
//bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
// "~/Scripts/jquery-{version}.js"));
bundles.UseCdn = true; //enable CDN support
//add link to jquery on the CDN
var jqueryCdnPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js";
bundles.Add(new ScriptBundle("~/bundles/jquery",
jqueryCdnPath).Include(
"~/Scripts/jquery-{version}.js"));
// Code removed for clarity.
}
Кажется, вам кажется, что вам нужно явно указать путь к вашему файлу на CDN.
CloudFront CDN (и я предполагаю, что многие другие) дает вам субдомен, который отражает ваши собственные. Когда вы нажмете http://uniquesubdomain.cloudfront.net/js/myfile.js?v=1
, он будет обслуживать http://mydomain.com/js/myfile.js?v=1
Таким образом вы можете просто префикс всех ваших ссылок с помощью http://uniquesubdomain.cloudfront.net/
, а ваши файлы - сервером из CloudFront.
Является ли функция связывания ASP.NET 4.5 совместимой с этим типом CDN? Есть ли встроенный способ привязки функции связывания всех своих ссылок с вашим доменом CDN?
Eg.
bundles.UseCdn = true;
var myBundle= new ScriptBundle("~/bundles/js", "https://uniquedomain.cloudfront.net/");
myBundle.Include("~/js/file1.js");
myBundle.Include("~/js/file2.js");
приведет к
<script src="https://uniquedomain.cloudfront.net/bundles/js?v=6y-qVPSK3RYOYHfPhOBDd92H4LjEjs-D3Hh2Yml6CXA1"></script>
Ответы
Ответ 1
Эта функциональность не встроена, но возможна с помощью нескольких небольших вспомогательных методов. Вот то, что я использую прямо сейчас:
public static class Cdn
{
private const string CdnRoot = "//cloudfrontdomainhere.com";
private static bool EnableCdn
{
get
{
bool enableCdn = false;
bool.TryParse(WebConfigurationManager.AppSettings["EnableCdn"], out enableCdn);
return enableCdn;
}
}
public static IHtmlString RenderScripts(string bundlePath)
{
if (EnableCdn)
{
string sourceUrl = CdnRoot + Scripts.Url(bundlePath);
return new HtmlString(string.Format("<script src=\"{0}\"></script>", sourceUrl));
}
return Scripts.Render(bundlePath);
}
public static IHtmlString RenderStyles(string bundlePath)
{
if (EnableCdn)
{
string sourceUrl = CdnRoot + Styles.Url(bundlePath);
return new HtmlString(string.Format("<link href=\"{0}\" rel=\"stylesheet\" />", sourceUrl));
}
return Styles.Render(bundlePath);
}
}
Обратите внимание, что у меня есть собственный параметр настройки, называемый EnableCdn, в разделе appSettings моего файла конфигурации. При вызове из представления Razor это создает правильный вывод, который добавляет домен CDN на пути.
В ваших файлах Razor просто создайте Cdn.RenderScripts( "~/pathtoscriptbundle" )
Ответ 2
Возможно, вы не точно, что ищете, но многие CDN теперь действуют как обратный прокси-сервер с использованием DNS, поэтому вам не нужно напрямую связывать свои активы. Я знаю, что Cloudflare делает это, и я уверен, что другие тоже тоже.
Ответ 3
Другим вариантом является использование метода Scripts или Styles RenderFormat. Это было особенно полезно для меня, поскольку я периодически настраивал tagFormat для обертывания ссылок в условных комментариях html или добавлял дополнительные атрибуты, такие как media = "screen, print". Код проще, потому что вы можете выполнить неудобную замену на строку, прежде чем она станет кодировкой HTML.
В качестве альтернативы вы можете иметь tagFormat как необязательный параметр для тех методов, где значение по умолчанию является строковыми константами, указанными ниже.
public class BundleHelper
{
public static readonly string StyleTagFormat = "<link href=\"{0}\" rel=\"stylesheet\"/>";
public static readonly string ScriptTagFormat = "<script src=\"{0}\"></script>"
/// <summary>
/// Customised script bundle rendering method with CDN support if optimizations and CDN enabled.
/// </summary>
public static IHtmlString RenderScriptFormat(string tagFormat, string path)
{
// Check for absolute url to ensure the standard framework support for CDN bundles, with a CdnPath still works.
if (AppSettings.Bundling.EnableCdn && !UriHelper.IsAbsoluteUrl(Scripts.Url(path).ToString()))
{
tagFormat = tagFormat.Replace(" src=\"{0}\"", String.Format(" src=\"{0}{{0}}\"", AppSettings.Bundling.BundlesCDNPrefixUrl));
}
return Scripts.RenderFormat(tagFormat, path);
}
/// <summary>
/// Customised styles bundle rendering method with CDN support if optimizations and CDN enabled.
/// </summary>
public static IHtmlString RenderStyleFormat(string tagFormat, string path)
{
// Check for absolute url to ensure the standard framework support for CDN bundles, with a CdnPath still works.
if (AppSettings.Bundling.EnableCdn && !UriHelper.IsAbsoluteUrl(Styles.Url(path).ToString()))
{
tagFormat = tagFormat.Replace(" href=\"{0}\"", String.Format(" href=\"{0}{{0}}\"", AppSettings.Bundling.BundlesCDNPrefixUrl));
}
return Styles.RenderFormat(tagFormat, path);
}
}
public class UriHelper
{
/// <summary>
/// Determines whether a url is absolute or not.
/// </summary>
/// <param name="url">Url string to test.</param>
/// <returns>true/false.</returns>
/// <remarks>
/// Examples:
/// ?IsAbsoluteUrl("hello")
/// false
/// ?IsAbsoluteUrl("/hello")
/// false
/// ?IsAbsoluteUrl("ftp//hello")
/// false
/// ?IsAbsoluteUrl("//hello")
/// true
/// ?IsAbsoluteUrl("ftp://hello")
/// true
/// ?IsAbsoluteUrl("http://hello")
/// true
/// ?IsAbsoluteUrl("https://hello")
/// true
/// </remarks>
public static bool IsAbsoluteUrl(string url)
{
Uri result;
return Uri.TryCreate(url, UriKind.Absolute, out result);
}
}
Ответ 4
Это невозможно, но вместо связки вы можете использовать текстовый шаблон для объединения JS файлов как один js и поместить его на CDN.
<#@ ... hostspecific="true" extension=".js">
<#
Write (System.IO.File.ReadAllText("a.js"));
Write (System.IO.File.ReadAllText("b.js"));
#>