golang html/template ExecuteTemplate 出错的字节是从哪里来的?

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

golang html/template ExecuteTemplate errant byte where is it coming from?

问题

背景
我正在尝试为Go编写一些GZIP中间件,但遇到了问题,因为http.DetectContentType()返回的是text/plain而不是text/html,所以我追踪到第一个被写入的文本是一些错误的字节,我仍在努力追踪它。我知道有很多解决方法,比如显式设置ContentType或在执行模板时使用bytes.Buffer并一次性写入所有内容,但我真的想找出是什么原因导致写入这个单个字节。

示例
这里有一个非常假设的示例,展示了相同的问题https://play.golang.org/p/SSrWP9jLRq

运行时,你会看到打印的第一件事是:"LEN BYTES: 1 String: "

嫌疑人
正如示例所示,似乎这行"{{template "header" .}}"在content模板中是罪魁祸首,但为什么会输出这个额外的内容呢?

问题
有人知道这个错误字节是从哪里来的吗?请查看示例中的html header、footer和content模板。

英文:

Background
I was trying to write some GZIP middleware for Go, but ran into a problem as http.DetectContentType() was returning text/plain instead of text/html so I tracked it down to the first text being written was some sort or errant byte, that I am still trying to track down. I know there are lots of ways around it, like setting the ContentType explicitly or using a bytes.Buffer when Executing the template and writing all at once, but I really want to find out what is causing this single byte to be written.

Example
Here is a very contrived example that shows the same issue https://play.golang.org/p/SSrWP9jLRq

when run you will see the first thing that is printed is: "LEN BYTES: 1 String: "

Suspects
It appears, as the example shows, that this line "{{template "header" .}}" within the content template is the culprit, but why would it be outputting this extra content.

Question
Does anybody know where this errant byte is coming from? see the html header, footer and content templates in the example.

答案1

得分: 1

因为模板内容紧跟在define指令的闭合大括号后面,所以根模板、头部模板和尾部模板都以换行符开头。

在模板调用子模板之前,会先刷新输出,所以在开头写入一个换行符。

将定义改为以下形式以消除额外的换行符:

header = `{{define "header"}}<!DOCTYPE html>
...
content = `{{define "root"}}{{template "header" .}}

参考 https://play.golang.org/p/AzD98cD7c0 进行修复。

在Go 1.6或更高版本中,可以在动作的末尾添加一个减号来修剪动作后面的空白字符:

header = `{{define "header" -}}

...

content = `{{define "root" -}}

{{template "header" .}}
...

在动作的开头添加一个减号来修剪动作前面的空白字符。

英文:

Because template content starts immediately following the closing braces in the define directive, the root, header and footer templates start with a newline.

The single newline is written at the start because the template flushes output before invoking a sub-template.

Change the definitions to start with

header = `{{define &quot;header&quot;}}&lt;!DOCTYPE html&gt;
...
content = `{{define &quot;root&quot;}}{{template &quot;header&quot; .}}

to eliminate the extra newlines. See https://play.golang.org/p/AzD98cD7c0 for a fix.

In Go 1.6 or latter, add a minus sign at the end of the action to trim whitespace following the action:

	header = `{{define &quot;header&quot; -}}
&lt;!DOCTYPE html&gt;
...

	content = `{{define &quot;root&quot; -}}
{{template &quot;header&quot; .}}
...

Add a minus sign to the beginning of the action to trim whitespace before for the action.

huangapple
  • 本文由 发表于 2016年2月2日 08:59:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/35143278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定