Подтвердить что ты не робот

Использование 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>
4b9b3361

Ответ 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"));
 #>