考虑这个标记:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Page title</title>
<link rel="stylesheet" href="css/layouts.css" type="text/css" media="all">
<noscript>
<link rel="stylesheet" href="css/layouts_nojs.css" type="text/css" media="all">
</noscript>
<script src="js/jquery.min.js" charset="utf-8"></script>
</head>
<body>
我使用Thymeleaf作为引擎,但输出代码结果为:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Page title</title>
<link rel="stylesheet" href="css/layouts.css" type="text/css" media="all">
</head>
<body>
<noscript>
<link rel="stylesheet" href="css/layouts_nojs.css" type="text/css" media="all">
</noscript>
<script src="js/jquery.min.js" charset="utf-8"></script>
如何防止此行为?
答案 0 :(得分:4)
Thymeleaf最后一个版本,2.1.3,使用nekohtml库,这个库在1.9.14之前的某些版本中有一个错误,可以避免在头部使用noscript,所以可能你使用的是旧版本,请查看你的依赖项。
但是,这并不是全部,所有高级版本都不允许在头部内,使用带有子元素的元素,因此头部中的noscript不能支持其中的链接标记。使用您的代码,结果必须是:<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Page title</title>
<link rel="stylesheet" href="css/layouts.css" type="text/css" media="all">
<noscript>
</noscript><link rel="stylesheet" href="css/layouts_nojs.css" type="text/css" media="all">
<script src="js/jquery.min.js" charset="utf-8"></script>
</head>
<body>
这个问题要解决得更复杂,需要进行更深层次的更改。
解决方法:
1 - 使用自定义LegacyHtml5TemplateParser,您可以在nekohtml库的HTMLConfiguration中将“http://cyberneko.org/html/features/parse-noscript-content”功能设置为false,这样就不会解析noscript元素的内容,因此被视为文本,以便使用百里香叶的动态代码,设置:noscript开始标记中的内联属性到文本,并在内部使用标记 Tutorial: Using Thymeleaf, 12.1 Text inlining
一个例子:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Page title</title>
<link rel="stylesheet" href="css/layouts.css" type="text/css" media="all">
<noscript th:inline="text">
<link rel="stylesheet" href="[[@{css/layouts_nojs.css}]]" type="text/css" media="all">
</noscript>
<script src="js/jquery.min.js" charset="utf-8"></script>
</head>
<body>
2 - 另一种可能性,更复杂,需要为thymeleaf使用自定义LegacyHtml5TemplateParser,以及为nekohtml使用自定义HTMLTagBalancer,因此您可以控制head是否包含带子项的元素。这涉及创建一系列类来覆盖nekohtml行为,这些类如下:
HTMLAugmentations,HTMLConfiguration,HTMLScanner,HTMLTagBalancer,LostText,ObjectFactory,SecuritySupport,SecuritySupport12。
您必须从包中的nekohtml库复制原始源,并根据此包更改对其进行相应修改,并在LegacyHtml5TemplateParser中使用您的新HTMLConfiguration类。
对于此变通办法,在HTMLTagBalancer中,更改以下行:
if ((fElementStack.top > 1 && fElementStack.peek().element.code == HTMLElements.SCRIPT)
|| (fElementStack.top > 2 && fElementStack.data[fElementStack.top-2].element.code == HTMLElements.HEAD)) {
与其他人一起:
if (fElementStack.top > 1 && fElementStack.peek().element.code == HTMLElements.SCRIPT) {
//|| (fElementStack.top > 2 && fElementStack.data[fElementStack.top-2].element.code == HTMLElements.HEAD)) {
优点:让你为百里香的头部定义th:block标签。
缺点:如果您想将nekohtml库版本更改为较新版本,则必须确保更改不会影响您的代码。
答案 1 :(得分:0)
将脚本移到noscript样式表上方
答案 2 :(得分:0)
在页面解析html并执行javascript时,将noscript写入文档。
<script type="text/javascript">
document.write('<noscript><div>example</div></noscript>');
</script>
答案 3 :(得分:0)
6年后,当我尝试实施Facebook Pixel No Script Tag时遇到了同样的问题。
好吧,这是我的解决方法:
fragments / general.html
<head th:fragment="headFragment">
<!-- [...] -->
<th:block th:insert="~{fragments/general :: fbpNoScriptFragment}" />
<!-- [...] -->
</head>
<!-- The noscript below will be inserted in the <head> fragment above, just not directly -->
<noscript th:fragment="fbpNoScriptFragment">
<img height="1" width="1" style="display:none"
th:attr="src='https://www.facebook.com/tr?id=' + ${fbp_id} + '&ev=PageView&noscript=1'"/>
</noscript>
在我的“主”模板文件中:
<head>
<!-- [...] -->
<th:block th:include="fragments/general.html :: headFragment" />
<!-- [...] -->
</head>
现在它可以工作了,所以就像@Jack Froilson解释的那样,导致此错误的原因似乎没有,它不是“链接”该错误,而是通过间接插入它似乎可以正常工作。