Почему я вижу ZgotmplZ в моих выходных шаблонах Go HTML?
Когда я вызываю функцию шаблона Go для вывода HTML, она отображает ZgotmplZ
,
Образец кода:
http://play.golang.org/p/tfuJa_pFkm
package main
import (
"html/template"
"os"
)
func main() {
funcMap := template.FuncMap{
"printSelected": func(s string) string {
if s == "test" {
return `selected="selected"`
}
return ""
},
"safe": func(s string) template.HTML {
return template.HTML(s)
},
}
template.Must(template.New("Template").Funcs(funcMap).Parse(`
<option {{ printSelected "test" }} {{ printSelected "test" | safe }} >test</option>
`)).Execute(os.Stdout, nil)
}
Выход:
<option ZgotmplZ ZgotmplZ >test</option>
7 ответов
"ZgotmplZ" - это специальное значение, которое указывает, что небезопасный контент достиг контекста CSS или URL во время выполнения. Выходные данные примера будут такими:
<img src="#ZgotmplZ">
Вы можете добавить функцию safe и attr в шаблон funcMap:
основной пакет
import (
"html/template"
"os"
)
func main() {
funcMap := template.FuncMap{
"attr":func(s string) template.HTMLAttr{
return template.HTMLAttr(s)
},
"safe": func(s string) template.HTML {
return template.HTML(s)
},
}
template.Must(template.New("Template").Funcs(funcMap).Parse(`
<option {{ .attr |attr }} >test</option>
{{.html|safe}}
`)).Execute(os.Stdout, map[string]string{"attr":`selected="selected"`,"html":`<option selected="selected">option</option>`})
}
Вывод будет выглядеть так:
<option selected="selected" >test</option>
<option selected="selected">option</option>
Вы можете определить некоторые другие функции, которые могут преобразовывать строку в template.CSS, template.JS, template.JSStr, template.URL и т. Д.
У меня была похожая проблема с <img src="{{myfunction}}">
где myfunction возвращает закодированное изображение.
Наконец я решил это когда вместо строковой функции возвращаю template.URL(mystring)
,
package main
import (
"html/template"
"os"
)
type T struct {
HTML template.HTML
ATTR template.HTMLAttr
URL template.URL
JS template.JS
CSS template.CSS
}
func main() {
data := T{
HTML: `<div>test div</div>`,
ATTR: `selected="selected"`,
URL: `https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg`,
CSS: `font-size: 15px`,
JS: `console.log("hello world")`,
}
template.Must(template.New("Template").Parse(`
{{.HTML}}
<option {{.ATTR}} style="{{.CSS}}">test</option>
<script>{{.JS}}</script>
<img src="{{.URL}}">
`)).Execute(os.Stdout, data)
}
выход
<div>test div</div>
<option selected="selected" style="font-size: 15px">test</option>
<script>console.log("hello world")</script>
<img src="https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg">
Вы пытаетесь вывести HTML в месте, где template / html считает небезопасным (например, внутри элемента HTML, например так:
<option {{ printSelected }}>
Я не могу найти никакого способа убедить его в том, что это безопасно (включая возвращение template.HTML вместо string); единственная альтернатива, которую я нашел, это переписать шаблон, в этом примере вместо этого используйте вывод bool:
<option {{ if printSelected }}selected{{ end }}>
Самый простой способ:
import "html/template"
yourhref = template.URL(yourhref)
Вы должны завернуть строку в HTMLAttr
, который был разработан для текста, который вставляется между угловыми скобками. Согласно документации:
https://golang.org/pkg/html/template/
HTMLAttr инкапсулирует атрибут HTML из доверенного источника, например,
dir="ltr"
,Использование этого типа представляет угрозу безопасности: инкапсулированный контент должен поступать из надежного источника, так как он будет дословно включен в выходные данные шаблона.
type HTMLAttr string
Я пытался вставить изображение из frontmatter в свой шаблон, но продолжал получать ту же ошибку. Я решил это так:
{{ if isset .Params "image" }}
{{ $myVar := print .Params.image }}
<img src="{{ $myVar }}">
{{ end }}
Обратите внимание, что я сначала сохраняю.Params.image
как переменную, а затем вставьте ее как моюsrc
.