为什么html/template不显示所有的HTML条件注释?

huangapple go评论118阅读模式
英文:

Why doesn't html/template show all html conditional comments?

问题

我有一个简单的Go HTML模板,其中包含HTML条件注释:

package main

import (
	"html/template"
	"os"
)

var body = `<!doctype html>
<html>
  <head>
    <!--[if !IE]><!--><script src="http://code.jquery.com/jquery-2.0.3.min.js"></script><!--<![endif]-->
    <!--[if gte IE 9]><script src="http://code.jquery.com/jquery-2.0.3.min.js"></script><![endif]-->
    <!--[if lt IE 9]><script src="http://code.jquery.com/jquery-1.10.2.min.js"></script><![endif]-->

  </head>
</html>`

func main() {
	tmp := template.Must(template.New("tmp").Parse(body))
	tmp.Execute(os.Stdout, nil)

}

这将产生:

<!doctype html>
<html>
  <head>
    <script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
    
    
    
  </head>
</html>

为什么html/template在编译后会删除这些条件注释?

英文:

I have a simple Go HTML template which contains HTML conditional comments:

package main

import (
	&quot;html/template&quot;
	&quot;os&quot;
)

var body = `&lt;!doctype html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;!--[if !IE]&gt;&lt;!--&gt;&lt;script src=&quot;http://code.jquery.com/jquery-2.0.3.min.js&quot;&gt;&lt;/script&gt;&lt;!--&lt;![endif]--&gt;
    &lt;!--[if gte IE 9]&gt;&lt;script src=&quot;http://code.jquery.com/jquery-2.0.3.min.js&quot;&gt;&lt;/script&gt;&lt;![endif]--&gt;
    &lt;!--[if lt IE 9]&gt;&lt;script src=&quot;http://code.jquery.com/jquery-1.10.2.min.js&quot;&gt;&lt;/script&gt;&lt;![endif]--&gt;

  &lt;/head&gt;
&lt;/html&gt;`

func main() {
	tmp := template.Must(template.New(&quot;tmp&quot;).Parse(body))
	tmp.Execute(os.Stdout, nil)

}

This produces:

&lt;!doctype html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;script src=&quot;http://code.jquery.com/jquery-2.0.3.min.js&quot;&gt;&lt;/script&gt;
    
    

  &lt;/head&gt;
&lt;/html&gt;

Why does html/template remove those conditional comments after compiling?

答案1

得分: 10

我的解决方法是重新实现被提交#938597eab997移除的noescape助手函数。

funcMap := template.FuncMap{
    "noescape": func(s string) template.HTML {
        return template.HTML(s) 
    },
}

然后在你的模板中使用它:

<!DOCTYPE html>
{{noescape "<!--[if lt IE 9]>"}}
<html class="old-ie">{{noescape "<![endif]-->"}}
英文:

My workaround is to reimplement the noescape helper that was removed on commit #938597eab997

funcMap := template.FuncMap{
    &quot;noescape&quot;: func(s string) template.HTML {
        return template.HTML(s) 
    },
}

and then use it in your template:

&lt;!DOCTYPE html&gt;
{{noescape &quot;&lt;!--[if lt IE 9]&gt;&quot;}}&lt;html class=&quot;old-ie&quot;&gt;{{noescape &quot;&lt;![endif]--&gt;&quot;}}

答案2

得分: 9

由于你的问题是“为什么”,我将尝试解释为什么注释会被删除。

首先,html/template包的目的是为了保证安全性。文档中指出:

> Package template (html/template) 实现了用于生成安全的HTML输出的数据驱动模板。

这是通过上下文敏感的转义来实现的。在一个Golang-nuts的讨论帖子中,Kyle Lemons提供了一个例子,其中条件注释会破坏这种安全性,除非注释被删除:

&lt;p&gt;
&lt;!--[if lt IE 9]&gt;&lt;script&gt;&lt;![endif]--&gt;
{{.Stuff}}
&lt;!--[if lt IE 9]&gt;&lt;/script&gt;&lt;![endif]--&gt;
&lt;/p&gt;

在这种情况下,{{.Stuff}}中的任何值都将在某些浏览器上作为Javascript执行,因此应该进行转义以确保安全。这将要求模板引擎意识到注释的这种特定于浏览器的解释,以及所有其他浏览器中的非标准行为。这是不可行的。

相反,html/template被设计为删除任何注释,以确保生成的HTML对于任何注入攻击都是安全的。

解决方法

正如Dave提到的,可以使用template.HTML来插入这样的注释。然而,由于安全风险,template.HTML文档指出(我强调):

>HTML 封装了一个已知安全的HTML文档片段。它不应该用于来自第三方的HTML,或者包含未关闭标签或注释的HTML。

英文:

Since your question was Why, I will try to explain why comments are stripped away.

First of all, the purpose of the html/template package is to be safe. The documentation states:

> Package template (html/template) implements data-driven templates for generating HTML output safe against code injection.

This is done through context-sensitive escaping. In a Golang-nuts thread Kyle Lemons provide an example where conditional comments would currently break this safety unless the comments were stripped away:

&lt;p&gt;
&lt;!--[if lt IE 9]&gt;&lt;script&gt;&lt;![endif]--&gt;
{{.Stuff}}
&lt;!--[if lt IE 9]&gt;&lt;/script&gt;&lt;![endif]--&gt;
&lt;/p&gt;

In this case, any value in {{.Stuff}} will be executed as Javascript on some browsers and should therefore be escaped to be safe . This would require the template engine to be aware of this browser-specific interpretation of the comment, and any other non-standard behavior in all the browsers out there. This is not feasible.

Instead, html/template was designed to strip away any comments to ensure that the HTML it produces is safe from any injection attack.

Workaround

As mentioned by Dave, it is possible to use template.HTML to insert such comments. However, because of the security risk, the documentation for template.HTML states (my emphasis):

>HTML encapsulates a known safe HTML document fragment. It should not be used for HTML from a third-party, or HTML with unclosed tags or comments.

答案3

得分: 1

看起来这个问题在golang-nuts组讨论过:
https://groups.google.com/forum/#!msg/golang-nuts/8y6by6SERyU/XQRnbw3aBhwJ

简而言之,
Go的html/template会去掉所有的HTML注释,并且不会解释条件注释,因为它们不是标准的一部分。

此外,{{noescape}}指令已被移除:http://code.google.com/p/go/issues/detail?id=3528

英文:

It looks that the problem was discussed on golang-nuts group:
https://groups.google.com/forum/#!msg/golang-nuts/8y6by6SERyU/XQRnbw3aBhwJ

TL;DR
Go html/template strips of all html commments, and didn't interpret conditional comments since they are not a part of the standard.

Also the {{noescape}} directive has been removed: http://code.google.com/p/go/issues/detail?id=3528

答案4

得分: 0

条件注释仅受到Internet Explorer的支持,并且我找不到它是任何标准的一部分。

来自Wikipedia

条件注释是由Microsoft Internet Explorer在HTML源代码中解释的条件语句。条件注释可用于向Internet Explorer提供和隐藏代码。

HTML中的条件注释首次出现在Microsoft的Internet Explorer 5浏览器中,尽管现在已经不再支持。在Internet Explorer 10中,当页面处于标准模式(文档模式10)时,不支持HTML条件注释。

英文:

Conditional commenting was only supported by Internet Explorer and isn't part of any standard that I can find.

From Wikipedia:

>Conditional comments are conditional statements interpreted by Microsoft Internet Explorer in HTML source code. Conditional comments can be used to provide and hide code to and from Internet Explorer.
>
>Conditional comments in HTML1 first appeared in Microsoft's Internet Explorer 5 browser, although support has now been deprecated. In Internet Explorer 10 HTML conditional comments are not supported when the page is in standards mode (document mode 10)

答案5

得分: 0

给html/template输出添加HTML注释的几个示例:

  1. 使用HTML类型添加注释:
    http://play.golang.org/p/mYj4rxVfHW

  2. 使用添加的noescape函数(返回HTML):
    http://play.golang.org/p/y61Hysfs3Y

英文:

adding a couple of examples of adding HTML comments to the html/template output:

  1. adding comment using the HTML type:
    http://play.golang.org/p/mYj4rxVfHW

  2. using an added noescape function (which returns HTML):
    http://play.golang.org/p/y61Hysfs3Y

huangapple
  • 本文由 发表于 2013年12月16日 20:19:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/20610820.html