ASP.NET Core 的 "asp-fallback-*" CDN 标签助手如何工作?
How do ASP.NET Core's "asp-fallback-*" CDN tag helpers work?
我了解 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 加载 bootstrap,如果 CDN 关闭则加载本地副本。
但是它是如何决定这样做的呢?我假设它会检查 asp-fallback-test-class
、asp-fallback-test-property
和 asp-fallback-test-value
。但是这些属性是什么意思?
如果我想从 CDN 连接一些其他库,我需要为它们提供一些东西,但我不确定放在那里什么。
有很多这样的例子,但我找不到关于它如何工作的解释。
更新
我并不是真的想了解标签助手是如何工作的——它们是如何呈现的,等等。我试图了解如何为这些属性选择值。例如,jQuery 后备脚本通常有 asp-fallback-test="window.jQuery"
,这是有道理的 - 这是一个测试,看看 jQuery 是否已加载。但是我上面展示的那些是完全不同的。如何选择它们?如果我想使用其他一些 CDN 交付的库,我需要为这些属性指定值……我会使用什么?为什么选择这些人 bootstrap?
更新 2
要了解回退过程本身是如何工作的,以及这些标签是如何编写的,请参阅@KirkLarkin 的回答。要了解为什么使用这些测试值,请参阅我的回答。
更新 3
在 bootstrap 5 中,sr-only
class 重命名为 visually-hidden
。
TL;DR:
- 一个
<meta>
标签被添加到 DOM 中,它的 CSS class 为 sr-only
。
- 附加JavaScript写入DOM,其中:
- 找到所述
<meta>
元素。
- 检查所述元素是否具有设置为
absolute
. 的 CSS 属性 position
- 如果没有设置这样的 属性 值,将向 DOM 写入一个额外的
<link>
元素,href
为 ~/lib/bootstrap/dist/css/bootstrap.min.css
。
针对您的 <link>
元素运行的 LinkTagHelper
class 在输出 HTML 中插入一个 <meta>
元素,该元素被赋予 CSS class 个 sr-only
。该元素最终看起来像这样:
<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 资源
FallbackTestProperty
和FallbackTestValue
,分别从属性asp-fallback-test-property
和asp-fallback-test-value
中得到。
那么,让我们看一下 JavaScript 资源 (source),它归结为具有以下签名的函数:
function loadFallbackStylesheet(cssTestPropertyName, cssTestPropertyValue, fallbackHrefs, extraAttributes)
将它与我之前调用的注释的最后一行以及 asp-fallback-test-property
和 asp-fallback-test-value
的值结合起来,我们可以推断它是这样调用的:
loadFallbackStylesheet('position', 'absolute', ...)
我不会深入研究 fallbackHrefs
和 extraAttributes
参数,因为它们应该比较明显并且您自己可以轻松探索。
loadFallbackStylesheet
的实施并没有太大作用 - 我鼓励您自己探索完整的实施。这是来源的实际检查:
if (metaStyle && metaStyle[cssTestPropertyName] !== cssTestPropertyValue) {
for (i = 0; i < fallbackHrefs.length; i++) {
doc.write('<link href="' + fallbackHrefs[i] + '" ' + extraAttributes + '/>');
}
}
脚本获取相关的 <meta>
元素(假定它直接位于 <script>
本身之上)并简单地检查它是否具有 属性 的 position
设置为 absolute
。如果没有,额外的 <link>
元素被写入每个后备 URL.
的输出
好的,结合@KirkLarkin 的回答和常识,我想我现在明白了。
sr-only
应用于隐藏的 meta
元素。如果加载 bootstrap,则该元素将获得 position:absolute
的 css 值。这样就测试过了,如果是这样,那就说明Bootstrap已经加载了。
因此,对于任何库,您都需要选择一个只有该库才能做的事情的好例子,并相应地设置隐藏的 <meta>
标签的样式,然后指定要测试的 css 样式,以及您期望的价值是多少。
对于 javscript,它甚至更容易,因为您可以只测试库本身,它通常会在 window
或 DOM 中添加一些众所周知的变量。所以对于jQuery它是window.jQuery
,对于Bootstrap它可以被测试为window.jQuery && window.jQuery.fn && window.jQuery.fn.modal
等等。
我了解 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 加载 bootstrap,如果 CDN 关闭则加载本地副本。
但是它是如何决定这样做的呢?我假设它会检查 asp-fallback-test-class
、asp-fallback-test-property
和 asp-fallback-test-value
。但是这些属性是什么意思?
如果我想从 CDN 连接一些其他库,我需要为它们提供一些东西,但我不确定放在那里什么。
有很多这样的例子,但我找不到关于它如何工作的解释。
更新
我并不是真的想了解标签助手是如何工作的——它们是如何呈现的,等等。我试图了解如何为这些属性选择值。例如,jQuery 后备脚本通常有 asp-fallback-test="window.jQuery"
,这是有道理的 - 这是一个测试,看看 jQuery 是否已加载。但是我上面展示的那些是完全不同的。如何选择它们?如果我想使用其他一些 CDN 交付的库,我需要为这些属性指定值……我会使用什么?为什么选择这些人 bootstrap?
更新 2
要了解回退过程本身是如何工作的,以及这些标签是如何编写的,请参阅@KirkLarkin 的回答。要了解为什么使用这些测试值,请参阅我的回答。
更新 3
在 bootstrap 5 中,sr-only
class 重命名为 visually-hidden
。
TL;DR:
- 一个
<meta>
标签被添加到 DOM 中,它的 CSS class 为sr-only
。 - 附加JavaScript写入DOM,其中:
- 找到所述
<meta>
元素。 - 检查所述元素是否具有设置为
absolute
. 的 CSS 属性 - 如果没有设置这样的 属性 值,将向 DOM 写入一个额外的
<link>
元素,href
为~/lib/bootstrap/dist/css/bootstrap.min.css
。
position
- 找到所述
针对您的 <link>
元素运行的 LinkTagHelper
class 在输出 HTML 中插入一个 <meta>
元素,该元素被赋予 CSS class 个 sr-only
。该元素最终看起来像这样:
<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 资源
FallbackTestProperty
和FallbackTestValue
,分别从属性asp-fallback-test-property
和asp-fallback-test-value
中得到。
那么,让我们看一下 JavaScript 资源 (source),它归结为具有以下签名的函数:
function loadFallbackStylesheet(cssTestPropertyName, cssTestPropertyValue, fallbackHrefs, extraAttributes)
将它与我之前调用的注释的最后一行以及 asp-fallback-test-property
和 asp-fallback-test-value
的值结合起来,我们可以推断它是这样调用的:
loadFallbackStylesheet('position', 'absolute', ...)
我不会深入研究 fallbackHrefs
和 extraAttributes
参数,因为它们应该比较明显并且您自己可以轻松探索。
loadFallbackStylesheet
的实施并没有太大作用 - 我鼓励您自己探索完整的实施。这是来源的实际检查:
if (metaStyle && metaStyle[cssTestPropertyName] !== cssTestPropertyValue) {
for (i = 0; i < fallbackHrefs.length; i++) {
doc.write('<link href="' + fallbackHrefs[i] + '" ' + extraAttributes + '/>');
}
}
脚本获取相关的 <meta>
元素(假定它直接位于 <script>
本身之上)并简单地检查它是否具有 属性 的 position
设置为 absolute
。如果没有,额外的 <link>
元素被写入每个后备 URL.
好的,结合@KirkLarkin 的回答和常识,我想我现在明白了。
sr-only
应用于隐藏的 meta
元素。如果加载 bootstrap,则该元素将获得 position:absolute
的 css 值。这样就测试过了,如果是这样,那就说明Bootstrap已经加载了。
因此,对于任何库,您都需要选择一个只有该库才能做的事情的好例子,并相应地设置隐藏的 <meta>
标签的样式,然后指定要测试的 css 样式,以及您期望的价值是多少。
对于 javscript,它甚至更容易,因为您可以只测试库本身,它通常会在 window
或 DOM 中添加一些众所周知的变量。所以对于jQuery它是window.jQuery
,对于Bootstrap它可以被测试为window.jQuery && window.jQuery.fn && window.jQuery.fn.modal
等等。