ASP.NET Core的“asp-fallback- *”CDN标记助手如何工作?

问题描述 投票:10回答:2

我理解asp-fallback-*标签助手的作用。我不明白的是如何。

例如:

<link rel="stylesheet"
      href="//ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/css/bootstrap.min.css"
      asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
      asp-fallback-test-class="sr-only"
      asp-fallback-test-property="position"
      asp-fallback-test-value="absolute" />

这将从CDN加载引导程序,并在CDN关闭时加载本地副本。

但它如何决定呢?我假设它检查asp-fallback-test-classasp-fallback-test-propertyasp-fallback-test-value。但这些属性意味着什么?

如果我想从CDN上挂一些其他的库,我需要为那些提供一些东西,但我不知道该把它放在那里。

有很多这方面的例子,但是我找不到关于它是如何工作的解释。

UPDATE 我并不是真的想要了解标签助手的工作原理 - 它们是如何渲染的,等等。我试图了解如何为这些属性选择值。例如,jQuery回退脚本通常有asp-fallback-test="window.jQuery",这是有意义的 - 它是一个测试,看看jQuery是否已加载。但是我上面展示的那些是完全不同的。如何选择它们?如果我想使用其他一些CDN交付的库,我需要为这些属性指定值...我会用什么?为什么选择那些引导程序?

更新2 要了解回退过程本身的工作原理以及这些标记的编写方式,请参阅@ KirkLarkin的回答。要了解使用这些测试值的原因,请参阅我的回答。

c# asp.net-core razor asp.net-core-2.1 asp.net-core-tag-helpers
2个回答
9
投票

TL; DR:

  • <meta>标记添加到具有CSS类sr-only的DOM中。
  • 将额外的JavaScript写入DOM,其中: 找到所说的<meta>元素。 检查所述元素是否具有设置为position的CSS属性absolute。 如果没有设置这样的属性值,则使用<link>href将额外的~/lib/bootstrap/dist/css/bootstrap.min.css元素写入DOM。

针对LinkTagHelper元素运行的<link>类在输出HTML中插入一个<meta>元素,该元素被赋予了sr-only的CSS类。元素最终看起来像这样:

<meta name="x-stylesheet-fallback-test" content="" class="sr-only" />

生成元素的代码如下所示(源代码):

builder
    .AppendHtml("<meta name=\"x-stylesheet-fallback-test\" content=\"\" class=\"")
    .Append(FallbackTestClass)
    .AppendHtml("\" />");

不出所料,FallbackTestClass的值来自<link>asp-fallback-test-class属性。

插入此元素后,还会插入相应的<script>块(source)。该代码的开头是这样的:

// Build the <script /> tag that checks the effective style of <meta /> tag above and renders the extra
// <link /> tag to load the fallback stylesheet if the test CSS property value is found to be false,
// indicating that the primary stylesheet failed to load.
// GetEmbeddedJavaScript returns JavaScript to which we add '"{0}","{1}",{2});'
builder
    .AppendHtml("<script>")        
    .AppendHtml(JavaScriptResources.GetEmbeddedJavaScript(FallbackJavaScriptResourceName))
    .AppendHtml("\"")
    .AppendHtml(JavaScriptEncoder.Encode(FallbackTestProperty))
    .AppendHtml("\",\"")
    .AppendHtml(JavaScriptEncoder.Encode(FallbackTestValue))
    .AppendHtml("\",");

这里有一些有趣的事情:

  • 评论的最后一行,指的是占位符{0}{1}{2}
  • FallbackJavaScriptResourceName,表示输出到HTML中的JavaScript资源。
  • FallbackTestPropertyFallbackTestValue,分别来自asp-fallback-test-propertyasp-fallback-test-value属性。

那么,让我们看一下JavaScript资源(source),它归结为具有以下签名的函数:

function loadFallbackStylesheet(cssTestPropertyName, cssTestPropertyValue, fallbackHrefs, extraAttributes)

将此与我之前提到的评论的最后一行以及asp-fallback-test-propertyasp-fallback-test-value的值相结合,我们可以推断这是如此调用:

loadFallbackStylesheet('position', 'absolute', ...)

我不会深入研究fallbackHrefsextraAttributes参数,因为这些参数应该有点明显且易于自行探索。

loadFallbackStylesheet的实施并没有太大的作用 - 我鼓励您自己探索完整的实现。这是来源的实际检查:

if (metaStyle && metaStyle[cssTestPropertyName] !== cssTestPropertyValue) {
    for (i = 0; i < fallbackHrefs.length; i++) {
        doc.write('<link href="' + fallbackHrefs[i] + '" ' + extraAttributes + '/>');
    }
}

该脚本获取相关的<meta>元素(假设它直接位于<script>本身之上),并简单地检查它是否具有设置为positionabsolute属性。如果没有,则为每个回退URL将额外的<link>元素写入输出。


5
投票

好吧,我想我现在可以通过结合@ KirkLarkin的答案和常识来实现它。

sr-only适用于隐藏的meta元素。如果加载了bootstrap,那么该元素将获得qssxswpoi的css值。所以这是经过测试的,如果是这样,那就意味着Bootstrap已被加载。

因此,对于任何库,您需要选择一个只有库可以做的事情的好例子,并相应地设置隐藏的position:absolute标签的样式,然后指定要测试的css样式,以及您期望的值。

对于javscript来说,它更容易,因为你可以只测试库本身,它通常有一些众所周知的变量添加到<meta>或DOM的东西。所以对于jQuery来说,它是window,而对于Bootstrap,它可以被测试为window.jQuery等等。

© www.soinside.com 2019 - 2024. All rights reserved.