亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

directory search
archive archive/tar archive/zip bufio bufio(緩存) builtin builtin(內(nèi)置包) bytes bytes(包字節(jié)) compress compress/bzip2(壓縮/bzip2) compress/flate(壓縮/flate) compress/gzip(壓縮/gzip) compress/lzw(壓縮/lzw) compress/zlib(壓縮/zlib) container container/heap(容器數(shù)據(jù)結(jié)構(gòu)heap) container/list(容器數(shù)據(jù)結(jié)構(gòu)list) container/ring(容器數(shù)據(jù)結(jié)構(gòu)ring) context context(上下文) crypto crypto(加密) crypto/aes(加密/aes) crypto/cipher(加密/cipher) crypto/des(加密/des) crypto/dsa(加密/dsa) crypto/ecdsa(加密/ecdsa) crypto/elliptic(加密/elliptic) crypto/hmac(加密/hmac) crypto/md5(加密/md5) crypto/rand(加密/rand) crypto/rc4(加密/rc4) crypto/rsa(加密/rsa) crypto/sha1(加密/sha1) crypto/sha256(加密/sha256) crypto/sha512(加密/sha512) crypto/subtle(加密/subtle) crypto/tls(加密/tls) crypto/x509(加密/x509) crypto/x509/pkix(加密/x509/pkix) database database/sql(數(shù)據(jù)庫/sql) database/sql/driver(數(shù)據(jù)庫/sql/driver) debug debug/dwarf(調(diào)試/dwarf) debug/elf(調(diào)試/elf) debug/gosym(調(diào)試/gosym) debug/macho(調(diào)試/macho) debug/pe(調(diào)試/pe) debug/plan9obj(調(diào)試/plan9obj) encoding encoding(編碼) encoding/ascii85(編碼/ascii85) encoding/asn1(編碼/asn1) encoding/base32(編碼/base32) encoding/base64(編碼/base64) encoding/binary(編碼/binary) encoding/csv(編碼/csv) encoding/gob(編碼/gob) encoding/hex(編碼/hex) encoding/json(編碼/json) encoding/pem(編碼/pem) encoding/xml(編碼/xml) errors errors(錯誤) expvar expvar flag flag(命令行參數(shù)解析flag包) fmt fmt go go/ast(抽象語法樹) go/build go/constant(常量) go/doc(文檔) go/format(格式) go/importer go/parser go/printer go/scanner(掃描儀) go/token(令牌) go/types(類型) hash hash(散列) hash/adler32 hash/crc32 hash/crc64 hash/fnv html html html/template(模板) image image(圖像) image/color(顏色) image/color/palette(調(diào)色板) image/draw(繪圖) image/gif image/jpeg image/png index index/suffixarray io io io/ioutil log log log/syslog(日志系統(tǒng)) math math math/big math/big math/bits math/bits math/cmplx math/cmplx math/rand math/rand mime mime mime/multipart(多部分) mime/quotedprintable net net net/http net/http net/http/cgi net/http/cookiejar net/http/fcgi net/http/httptest net/http/httptrace net/http/httputil net/http/internal net/http/pprof net/mail net/mail net/rpc net/rpc net/rpc/jsonrpc net/smtp net/smtp net/textproto net/textproto net/url net/url os os os/exec os/signal os/user path path path/filepath(文件路徑) plugin plugin(插件) reflect reflect(反射) regexp regexp(正則表達式) regexp/syntax runtime runtime(運行時) runtime/debug(調(diào)試) runtime/internal/sys runtime/pprof runtime/race(競爭) runtime/trace(執(zhí)行追蹤器) sort sort(排序算法) strconv strconv(轉(zhuǎn)換) strings strings(字符串) sync sync(同步) sync/atomic(原子操作) syscall syscall(系統(tǒng)調(diào)用) testing testing(測試) testing/iotest testing/quick text text/scanner(掃描文本) text/tabwriter text/template(定義模板) text/template/parse time time(時間戳) unicode unicode unicode/utf16 unicode/utf8 unsafe unsafe
characters

  • import "html/template"

  • 概述

  • 索引

  • 示例

概觀

模板包(html/template)實現(xiàn)了數(shù)據(jù)驅(qū)動的模板,以便在代碼注入過程中安全地生成HTML輸出。它提供了與包文本/模板相同的接口,只要輸出是HTML,就應(yīng)該使用它來代替文本/模板。

這里的文檔側(cè)重于包的安全特性。有關(guān)如何自行編寫模板的信息,請參閱文本/模板的文檔。

介紹

該軟件包包裝文本/模板,以便您可以共享其模板API以安全地解析和執(zhí)行HTML模板。

tmpl, err := template.New("name").Parse(...)// 錯誤檢查已刪除err = tmpl.Execute(out, data)

如果成功,tmpl 現(xiàn)在將是注射安全的。否則, err 是 ErrorCode 文檔中定義的錯誤。

HTML模板將數(shù)據(jù)值視為應(yīng)該被編碼的純文本,以便它們可以安全地嵌入到HTML文檔中。轉(zhuǎn)義是上下文的,因此操作可以出現(xiàn)在 JavaScript,CSS和URI 上下文中。

這個包使用的安全模型假定模板作者是可信的,而 Execute 的數(shù)據(jù)參數(shù)不是。更多細節(jié)在下面提供。

示例

import "text/template"...t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")

產(chǎn)生

Hello, <script>alert('you have been pwned')</script>!

但在HTML /模板中的上下文自動轉(zhuǎn)義

import "html/template"...t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")

產(chǎn)生安全的、轉(zhuǎn)義過的HTML輸出

Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!

上下文

該軟件包可以理解 HTML,CSS,JavaScript和URI 。它給每個簡單的操作流水線增加了清理功能,所以給出了摘錄

<a href="/search?q={{.}}">{{.}}</a>

在解析時,每個 {{.}} 都會被覆蓋,以根據(jù)需要添加轉(zhuǎn)義函數(shù)。在這種情況下,它變成了

<a href="/search?q={{. | urlescaper | attrescaper}}">{{. | htmlescaper}}</a>

urlescaper,attrescaper和htmlescaper 是內(nèi)部轉(zhuǎn)義函數(shù)的別名。

錯誤

有關(guān)詳細信息,請參閱ErrorCode的文檔。

A fuller picture

在第一次閱讀時可以跳過此包評論的其余部分;它包含了解轉(zhuǎn)義上下文和錯誤消息所需的詳細信息。大多數(shù)用戶不需要了解這些細節(jié)。

上下文

假設(shè) {{.}} 是O'Reilly: How are <i>you</i>?,下表顯示了 {{.}} 在左側(cè)上下文中使用時的顯示方式。

Context                          {{.}} After{{.}}                            O'Reilly: How are &lt;i&gt;you&lt;/i&gt;?<a title='{{.}}'>                O&#39;Reilly: How are you?<a href="/{{.}}">                O&#39;Reilly: How are %3ci%3eyou%3c/i%3e?<a href="?q={{.}}">              O&#39;Reilly%3a%20How%20are%3ci%3e...%3f<a onx='f("{{.}}")'>             O\x27Reilly: How are \x3ci\x3eyou...?<a onx='f({{.}})'>               "O\x27Reilly: How are \x3ci\x3eyou...?"<a onx='pattern = /{{.}}/;'>     O\x27Reilly: How are \x3ci\x3eyou...\x3f

如果在不安全的上下文中使用,則可能會過濾掉該值:

Context                          {{.}} After<a href="{{.}}">                 #ZgotmplZ

因為“O'Reilly:”不是像“http:”這樣的允許協(xié)議。

如果{{.}}是無關(guān)緊要的詞left,那么它可以更廣泛地出現(xiàn),

Context                              {{.}} After{{.}}                                left<a title='{{.}}'>                    left<a href='{{.}}'>                     left<a href='/{{.}}'>                    left<a href='?dir={{.}}'>                left<a style="border-{{.}}: 4px">        left<a style="align: {{.}}">             left<a style="background: '{{.}}'>       left<a style="background: url('{{.}}')>  left<style>p.{{.}} {color:red}</style>   left

非字符串值可以在JavaScript上下文中使用。如果是

struct{A,B string}{ "foo", "bar" }

在轉(zhuǎn)義模板中

<script>var pair = {{.}};</script>

然后模板輸出是

<script>var pair = {"A": "foo", "B": "bar"};</script>

請參閱包 json 以了解如何封裝非字符串內(nèi)容以嵌入JavaScript上下文中。

鍵入的字符串

默認情況下,此包假定所有管道都生成純文本字符串。它添加了必要的轉(zhuǎn)義管道階段,以便在正確的上下文中正確安全地嵌入純文本字符串。

如果數(shù)據(jù)值不是純文本,則可以通過使用其類型對其進行標記來確保它不會過度轉(zhuǎn)義。

來自content.go的HTML,JS,URL和其他類型可以攜帶免于轉(zhuǎn)義的安全內(nèi)容。

模板

Hello, {{.}}!

可以調(diào)用

tmpl.Execute(out, template.HTML(`<b>World</b>`))

來生成

Hello, <b>World</b>!

而不是

Hello, &lt;b&gt;World&lt;b&gt;!

如果{{.}}是常規(guī)字符串,則會生成。

安全模型

https://rawgit.com/mikesamuel/sanitized-jquery-templates/trunk/safetemplate.html#problem_definition定義此包使用的“safe”。

這個包假定模板作者是可信的,Execute的數(shù)據(jù)參數(shù)不是,并試圖在不受信任的數(shù)據(jù)面前保留下面的屬性:

結(jié)構(gòu)保留屬性:“......當模板作者以安全模板語言編寫HTML標記時,瀏覽器會將輸出的相應(yīng)部分解釋為標記,而不管不受信任數(shù)據(jù)的值如何,對于其他結(jié)構(gòu)(如屬性邊界和JS和CSS字符串邊界?!?/p>

代碼效果屬性:“...只有模板作者指定的代碼才能運行,因為將模板輸出注入到頁面中,模板作者指定的所有代碼都應(yīng)該運行相同的結(jié)果?!?/p>

Least Surprise Property:“熟悉HTML,CSS 和 JavaScript 的開發(fā)人員(或代碼審查員),他們知道發(fā)生上下文自動轉(zhuǎn)移應(yīng)該能夠查看{ {.}} 并正確推斷出正在進行的清理?!?/p>

示例

package mainimport ("html/template""log""os")func main() {const tpl = `
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>{{.Title}}</title>
	</head>
	<body>
		{{range .Items}}<div>{{ . }}</div>{{else}}<div><strong>no rows</strong></div>{{end}}
	</body>
</html>`

	check := func(err error) {if err != nil {
			log.Fatal(err)}}
	t, err := template.New("webpage").Parse(tpl)check(err)

	data := struct {
		Title string
		Items []string}{
		Title: "My page",
		Items: []string{"My photos","My blog",},}

	err = t.Execute(os.Stdout, data)check(err)

	noItems := struct {
		Title string
		Items []string}{
		Title: "My another page",
		Items: []string{},}

	err = t.Execute(os.Stdout, noItems)check(err)}

示例(Autoescaping)

package mainimport ("html/template""log""os")func main() {
	check := func(err error) {if err != nil {
			log.Fatal(err)}}
	t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)check(err)
	err = t.ExecuteTemplate(os.Stdout, "T", "<script>alert('you have been pwned')</script>")check(err)}

示例(Escape)

package mainimport ("fmt""html/template""os")func main() {const s = `"Fran & Freddie's Diner" <tasty@example.com>`
	v := []interface{}{`"Fran & Freddie's Diner"`, ' ', `<tasty@example.com>`}

	fmt.Println(template.HTMLEscapeString(s))
	template.HTMLEscape(os.Stdout, []byte(s))
	fmt.Fprintln(os.Stdout, "")
	fmt.Println(template.HTMLEscaper(v...))

	fmt.Println(template.JSEscapeString(s))
	template.JSEscape(os.Stdout, []byte(s))
	fmt.Fprintln(os.Stdout, "")
	fmt.Println(template.JSEscaper(v...))

	fmt.Println(template.URLQueryEscaper(v...))}

索引

  • func HTMLEscape(w io.Writer, b []byte)

  • func HTMLEscapeString(s string) string

  • func HTMLEscaper(args ...interface{}) string

  • func IsTrue(val interface{}) (truth, ok bool)

  • func JSEscape(w io.Writer, b []byte)

  • func JSEscapeString(s string) string

  • func JSEscaper(args ...interface{}) string

  • func URLQueryEscaper(args ...interface{}) string

  • type CSS

  • type Error

  • func (e *Error) Error() string

  • type ErrorCode

  • type FuncMap

  • type HTML

  • type HTMLAttr

  • type JS

  • type JSStr

  • type Template

  • func Must(t *Template, err error) *Template

  • func New(name string) *Template

  • func ParseFiles(filenames ...string) (*Template, error)

  • func ParseGlob(pattern string) (*Template, error)

  • func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error)

  • func (t *Template) Clone() (*Template, error)

  • func (t *Template) DefinedTemplates() string

  • func (t *Template) Delims(left, right string) *Template

  • func (t *Template) Execute(wr io.Writer, data interface{}) error

  • func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error

  • func (t *Template) Funcs(funcMap FuncMap) *Template

  • func (t *Template) Lookup(name string) *Template

  • func (t *Template) Name() string

  • func (t *Template) New(name string) *Template

  • func (t *Template) Option(opt ...string) *Template

  • func (t *Template) Parse(text string) (*Template, error)

  • func (t *Template) ParseFiles(filenames ...string) (*Template, error)

  • func (t *Template) ParseGlob(pattern string) (*Template, error)

  • func (t *Template) Templates() []*Template

  • type URL

示例

Package Template (Block) Template (Glob) Template (Helpers) Template (Parsefiles) Template (Share) Package (Autoescaping) Package (Escape)

包文件

attr.go content.go context.go css.go doc.go error.go escape.go html.go js.go template.go transition.go url.go

func HTMLEscape

func HTMLEscape(w io.Writer, b []byte)

HTMLEscape 寫入到明文數(shù)據(jù) b 的轉(zhuǎn)義HTML 等價物中。

func HTMLEscapeString

func HTMLEscapeString(s string) string

HTMLEscapeString 返回純文本數(shù)據(jù)的轉(zhuǎn)義 HTML 等價物。

func HTMLEscaper

func HTMLEscaper(args ...interface{}) string

HTMLEscaper 返回其參數(shù)文本表示的轉(zhuǎn)義 HTML 等價物。

func IsTrue

func IsTrue(val interface{}) (truth, ok bool)

IsTrue報告該值是否為'true',意味著它的類型不為零,以及該值是否具有有意義的真值。這是 if 和其他此類行為所使用的真相的定義。

func JSEscape

func JSEscape(w io.Writer, b []byte)

JSEscape寫入 w 的純文本數(shù)據(jù) b 的逃逸 JavaScript 等價物。

func JSEscapeString

func JSEscapeString(s string) string

JSEscapeString 返回純文本數(shù)據(jù)的轉(zhuǎn)義 JavaScript 等價物。

func JSEscaper

func JSEscaper(args ...interface{}) string

JSEscaper 返回其參數(shù)的文本表示的轉(zhuǎn)義 JavaScript 等價物。

func URLQueryEscaper

func URLQueryEscaper(args ...interface{}) string

URLQueryEscape r 以適合于嵌入到 URL 查詢中的形式返回其參數(shù)的文本表示的轉(zhuǎn)義值。

type CSS

CSS封裝了與以下任何匹配的已知安全內(nèi)容:

1. CSS3樣式表的制作,例如`p {color:purple}`。2. CSS3規(guī)則生成,例如`a [href =?“https:”]。foo #bar`。3. CSS3聲明制作,如`color:red; 保證金:2px`。4. CSS3值的產(chǎn)生,例如`rgba(0,0,255,127)`。

請參閱http://www.w3.org/TR/css3-syntax/#parsing和https://web.archive.org/web/20090211114933/http://w3.org/TR/css3-syntax#style

使用此類型會帶來安全風險:封裝內(nèi)容應(yīng)來自可信來源,因為它將逐字包含在模板輸出中。

type CSS string

type Error

錯誤描述了模板轉(zhuǎn)義期間遇到的問題。

type Error struct {        // ErrorCode describes the kind of error.
        ErrorCode ErrorCode        // Node is the node that caused the problem, if known.        // If not nil, it overrides Name and Line.
        Node parse.Node        // Name is the name of the template in which the error was encountered.
        Name string        // Line is the line number of the error in the template source or 0.
        Line int        // Description is a human-readable description of the problem.
        Description string}

func (*Error) Error

func (e *Error) Error() string

type ErrorCode

ErrorCode 是一種錯誤的代碼。

type ErrorCode int

我們?yōu)檗D(zhuǎn)義模板時顯示的每個錯誤定義代碼,但轉(zhuǎn)義模板也可能在運行時失敗。

輸出:“ZgotmplZ”示例:

<img src="{{.X}}">where {{.X}} evaluates to `javascript:...`

討論:

"ZgotmplZ" is a special value that indicates that unsafe content reached a
CSS or URL context at runtime. The output of the example will be  <img src="#ZgotmplZ">If the data comes from a trusted source, use content types to exempt itfrom filtering: URL(`javascript:...`).
const (        // OK indicates the lack of an error.
        OK ErrorCode = iota        // ErrAmbigContext: "... appears in an ambiguous context within a URL"        // Example:        //   <a href="        //      {{if .C}}        //        /path/        //      {{else}}        //        /search?q=        //      {{end}}        //      {{.X}}        //   ">        // Discussion:        //   {{.X}} is in an ambiguous URL context since, depending on {{.C}},        //  it may be either a URL suffix or a query parameter.        //   Moving {{.X}} into the condition removes the ambiguity:        //   <a href="{{if .C}}/path/{{.X}}{{else}}/search?q={{.X}}">
        ErrAmbigContext        // ErrBadHTML: "expected space, attr name, or end of tag, but got ...",        //   "... in unquoted attr", "... in attribute name"        // Example:        //   <a href = /search?q=foo>        //   <href=foo>        //   <form na<e=...>        //   <option selected<        // Discussion:        //   This is often due to a typo in an HTML element, but some runes        //   are banned in tag names, attribute names, and unquoted attribute        //   values because they can tickle parser ambiguities.        //   Quoting all attributes is the best policy.
        ErrBadHTML        // ErrBranchEnd: "{{if}} branches end in different contexts"        // Example:        //   {{if .C}}<a href="{{end}}{{.X}}        // Discussion:        //   Package html/template statically examines each path through an        //   {{if}}, {{range}}, or {{with}} to escape any following pipelines.        //   The example is ambiguous since {{.X}} might be an HTML text node,        //   or a URL prefix in an HTML attribute. The context of {{.X}} is        //   used to figure out how to escape it, but that context depends on        //   the run-time value of {{.C}} which is not statically known.        //        //   The problem is usually something like missing quotes or angle        //   brackets, or can be avoided by refactoring to put the two contexts        //   into different branches of an if, range or with. If the problem        //   is in a {{range}} over a collection that should never be empty,        //   adding a dummy {{else}} can help.
        ErrBranchEnd        // ErrEndContext: "... ends in a non-text context: ..."        // Examples:        //   <div        //   <div title="no close quote>        //   <script>f()        // Discussion:        //   Executed templates should produce a DocumentFragment of HTML.        //   Templates that end without closing tags will trigger this error.        //   Templates that should not be used in an HTML context or that        //   produce incomplete Fragments should not be executed directly.        //        //   {{define "main"}} <script>{{template "helper"}}</script> {{end}}        //   {{define "helper"}} document.write(' <div title=" ') {{end}}        //        //   "helper" does not produce a valid document fragment, so should        //   not be Executed directly.
        ErrEndContext        // ErrNoSuchTemplate: "no such template ..."        // Examples:        //   {{define "main"}}<div {{template "attrs"}}>{{end}}        //   {{define "attrs"}}href="{{.URL}}"{{end}}        // Discussion:        //   Package html/template looks through template calls to compute the        //   context.        //   Here the {{.URL}} in "attrs" must be treated as a URL when called        //   from "main", but you will get this error if "attrs" is not defined        //   when "main" is parsed.
        ErrNoSuchTemplate        // ErrOutputContext: "cannot compute output context for template ..."        // Examples:        //   {{define "t"}}{{if .T}}{{template "t" .T}}{{end}}{{.H}}",{{end}}        // Discussion:        //   A recursive template does not end in the same context in which it        //   starts, and a reliable output context cannot be computed.        //   Look for typos in the named template.        //   If the template should not be called in the named start context,        //   look for calls to that template in unexpected contexts.        //   Maybe refactor recursive templates to not be recursive.
        ErrOutputContext        // ErrPartialCharset: "unfinished JS regexp charset in ..."        // Example:        //     <script>var pattern = /foo[{{.Chars}}]/</script>        // Discussion:        //   Package html/template does not support interpolation into regular        //   expression literal character sets.
        ErrPartialCharset        // ErrPartialEscape: "unfinished escape sequence in ..."        // Example:        //   <script>alert("\{{.X}}")</script>        // Discussion:        //   Package html/template does not support actions following a        //   backslash.        //   This is usually an error and there are better solutions; for        //   example        //     <script>alert("{{.X}}")</script>        //   should work, and if {{.X}} is a partial escape sequence such as        //   "xA0", mark the whole sequence as safe content: JSStr(`\xA0`)
        ErrPartialEscape        // ErrRangeLoopReentry: "on range loop re-entry: ..."        // Example:        //   <script>var x = [{{range .}}'{{.}},{{end}}]</script>        // Discussion:        //   If an iteration through a range would cause it to end in a        //   different context than an earlier pass, there is no single context.        //   In the example, there is missing a quote, so it is not clear        //   whether {{.}} is meant to be inside a JS string or in a JS value        //   context. The second iteration would produce something like        //        //     <script>var x = ['firstValue,'secondValue]</script>
        ErrRangeLoopReentry        // ErrSlashAmbig: '/' could start a division or regexp.        // Example:        //   <script>        //     {{if .C}}var x = 1{{end}}        //     /-{{.N}}/i.test(x) ? doThis : doThat();        //   </script>        // Discussion:        //   The example above could produce `var x = 1/-2/i.test(s)...`        //   in which the first '/' is a mathematical division operator or it        //   could produce `/-2/i.test(s)` in which the first '/' starts a        //   regexp literal.        //   Look for missing semicolons inside branches, and maybe add        //   parentheses to make it clear which interpretation you intend.
        ErrSlashAmbig        // ErrPredefinedEscaper: "predefined escaper ... disallowed in template"        // Example:        //   <div class={{. | html}}>Hello<div>        // Discussion:        //   Package html/template already contextually escapes all pipelines to        //   produce HTML output safe against code injection. Manually escaping        //   pipeline output using the predefined escapers "html" or "urlquery" is        //   unnecessary, and may affect the correctness or safety of the escaped        //   pipeline output in Go 1.8 and earlier.        //        //   In most cases, such as the given example, this error can be resolved by        //   simply removing the predefined escaper from the pipeline and letting the        //   contextual autoescaper handle the escaping of the pipeline. In other        //   instances, where the predefined escaper occurs in the middle of a        //   pipeline where subsequent commands expect escaped input, e.g.        //     {{.X | html | makeALink}}        //   where makeALink does        //     return `<a href="`+input+`">link</a>`        //   consider refactoring the surrounding template to make use of the        //   contextual autoescaper, i.e.        //     <a href="{{.X}}">link</a>        //        //   To ease migration to Go 1.9 and beyond, "html" and "urlquery" will        //   continue to be allowed as the last command in a pipeline. However, if the        //   pipeline occurs in an unquoted attribute value context, "html" is        //   disallowed. Avoid using "html" and "urlquery" entirely in new templates.
        ErrPredefinedEscaper)

type FuncMap

FuncMap是定義從名稱到函數(shù)映射的映射的類型。每個函數(shù)必須具有單個返回值,或者其中第二個具有類型錯誤的返回值。在這種情況下,如果第二個(error)參數(shù)在執(zhí)行過程中評估為非零,則執(zhí)行結(jié)束并執(zhí)行返回該錯誤。FuncMap與“text/template”中的FuncMap具有相同的基本類型,在這里復制,因此客戶端不需要導入“text/template”。

type FuncMap map[string]interface{}

type HTML

HTML 封裝了一個已知的安全HTML文檔片段。它不應(yīng)該用于來自第三方的HTML,或 HTML 不帶標簽或注釋的 HTML。由這個包轉(zhuǎn)義出來的聲音 HTML清理器和模板的輸出,對于使用 HTML 來說是很好的。

使用這種類型會帶來安全風險:封裝的內(nèi)容應(yīng)該來自可信來源,因為它將逐字包含在模板輸出中。

type HTML string

type HTMLAttr

HTMLAttr 封裝來自信任來源的 HTML 屬性,例如dir="ltr"。

使用這種類型會帶來安全風險:封裝的內(nèi)容應(yīng)該來自可信來源,因為它將逐字包含在模板輸出中。

type HTMLAttr string

type JS

例如,JS封裝了一個已知的安全EcmaScript5表達式(x + y \* z())。模板作者負責確保類型化表達式不會打破預期的優(yōu)先順序,并且在傳遞像“{ foo: bar() }\n'foo'”這樣的表達式時不存在語句/表達式模糊性,這兩個表達式都是有效的表達和一個有著非常不同含義的有效程序。

使用這種類型會帶來安全風險:封裝的內(nèi)容應(yīng)該來自可信來源,因為它將逐字包含在模板輸出中。

使用 JS 來包含有效但不可信的 JSON 是不安全的。一個安全的選擇是使用 json.Unmarshal解析JSON ,然后將生成的對象傳遞到模板中,在 JavaScript 上下文中將其轉(zhuǎn)換為清理過的 JSON 。

type JS string

type JSStr

JSStr 在 JavaScript 表達式中封裝了一系列用于嵌入在引號之間的字符序列。該字符串必須與一系列 StringCharacters 匹配:

StringCharacter :: SourceCharacter but not `\` or LineTerminator                 | EscapeSequence

請注意,LineContinuations 是不允許的。 JSStr("foo\nbar")  是很好的,但 JSStr("foo\\nbar") 不是。

使用這種類型會帶來安全風險:封裝的內(nèi)容應(yīng)該來自可信來源,因為它將逐字包含在模板輸出中。

type JSStr string

type Template

模板是一個來自“text/template(文本/模板)”的專用模板,可以生成安全的HTML文檔片段。

type Template struct {        // The underlying template's parse tree, updated to be HTML-safe.
        Tree *parse.Tree        // contains filtered or unexported fields}

示例(塊)

package mainimport ("html/template""log""os""strings")func main() {const (
		master  = `Names:{{block "list" .}}{{"\n"}}{{range .}}{{println "-" .}}{{end}}{{end}}`
		overlay = `{{define "list"}} {{join . ", "}}{{end}} `)var (
		funcs     = template.FuncMap{"join": strings.Join}
		guardians = []string{"Gamora", "Groot", "Nebula", "Rocket", "Star-Lord"})
	masterTmpl, err := template.New("master").Funcs(funcs).Parse(master)if err != nil {
		log.Fatal(err)}
	overlayTmpl, err := template.Must(masterTmpl.Clone()).Parse(overlay)if err != nil {
		log.Fatal(err)}if err := masterTmpl.Execute(os.Stdout, guardians); err != nil {
		log.Fatal(err)}if err := overlayTmpl.Execute(os.Stdout, guardians); err != nil {
		log.Fatal(err)}}

示例(Glob)

這里我們演示從目錄加載一組模板。

代碼:

// Here we create a temporary directory and populate it with our sample// template definition files; usually the template files would already// exist in some location known to the program.dir := createTestDir([]templateFile{        // T0.tmpl is a plain template file that just invokes T1.        {"T0.tmpl", `T0 invokes T1: ({{template "T1"}})`},        // T1.tmpl defines a template, T1 that invokes T2.        {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},        // T2.tmpl defines a template T2.        {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},})// Clean up after the test; another quirk of running as an example.defer os.RemoveAll(dir)// pattern is the glob pattern used to find all the template files.pattern := filepath.Join(dir, "*.tmpl")// Here starts the example proper.// T0.tmpl is the first name matched, so it becomes the starting template,// the value returned by ParseGlob.tmpl := template.Must(template.ParseGlob(pattern))err := tmpl.Execute(os.Stdout, nil)if err != nil {
        log.Fatalf("template execution: %s", err)}

輸出:

T0 invokes T1: (T1 invokes T2: (This is T2))

示例(助手)

此示例演示了共享某些模板并在不同環(huán)境中使用它們的一種方法。在這個變體中,我們手動添加多個驅(qū)動模板到現(xiàn)有的一組模板。

代碼:

// Here we create a temporary directory and populate it with our sample// template definition files; usually the template files would already// exist in some location known to the program.dir := createTestDir([]templateFile{        // T1.tmpl defines a template, T1 that invokes T2.        {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},        // T2.tmpl defines a template T2.        {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},})// Clean up after the test; another quirk of running as an example.defer os.RemoveAll(dir)// pattern is the glob pattern used to find all the template files.pattern := filepath.Join(dir, "*.tmpl")// Here starts the example proper.// Load the helpers.templates := template.Must(template.ParseGlob(pattern))// Add one driver template to the bunch; we do this with an explicit template definition._, err := templates.Parse("{{define `driver1`}}Driver 1 calls T1: ({{template `T1`}})\n{{end}}")if err != nil {
        log.Fatal("parsing driver1: ", err)}// Add another driver template._, err = templates.Parse("{{define `driver2`}}Driver 2 calls T2: ({{template `T2`}})\n{{end}}")if err != nil {
        log.Fatal("parsing driver2: ", err)}// We load all the templates before execution. This package does not require// that behavior but html/template's escaping does, so it's a good habit.err = templates.ExecuteTemplate(os.Stdout, "driver1", nil)if err != nil {
        log.Fatalf("driver1 execution: %s", err)}err = templates.ExecuteTemplate(os.Stdout, "driver2", nil)if err != nil {
        log.Fatalf("driver2 execution: %s", err)}

輸出:

Driver 1 calls T1: (T1 invokes T2: (This is T2))Driver 2 calls T2: (This is T2)

示例(Parsefiles)

這里我們演示從不同目錄中的文件加載一組模板

代碼:

// Here we create different temporary directories and populate them with our sample// template definition files; usually the template files would already// exist in some location known to the program.dir1 := createTestDir([]templateFile{        // T1.tmpl is a plain template file that just invokes T2.        {"T1.tmpl", `T1 invokes T2: ({{template "T2"}})`},})dir2 := createTestDir([]templateFile{        // T2.tmpl defines a template T2.        {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},})// Clean up after the test; another quirk of running as an example.defer func(dirs ...string) {        for _, dir := range dirs {
                os.RemoveAll(dir)        }}(dir1, dir2)// Here starts the example proper.// Let's just parse only dir1/T0 and dir2/T2paths := []string{
        filepath.Join(dir1, "T1.tmpl"),
        filepath.Join(dir2, "T2.tmpl"),}tmpl := template.Must(template.ParseFiles(paths...))err := tmpl.Execute(os.Stdout, nil)if err != nil {
        log.Fatalf("template execution: %s", err)}

輸出:

T1 invokes T2: (This is T2)

示例(Share)

本示例演示如何將一組驅(qū)動程序模板與不同的輔助程序模板集一起使用。

編碼:

// Here we create a temporary directory and populate it with our sample// template definition files; usually the template files would already// exist in some location known to the program.dir := createTestDir([]templateFile{        // T0.tmpl is a plain template file that just invokes T1.        {"T0.tmpl", "T0 ({{.}} version) invokes T1: ({{template `T1`}})\n"},        // T1.tmpl defines a template, T1 that invokes T2. Note T2 is not defined        {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},})// Clean up after the test; another quirk of running as an example.defer os.RemoveAll(dir)// pattern is the glob pattern used to find all the template files.pattern := filepath.Join(dir, "*.tmpl")// Here starts the example proper.// Load the drivers.drivers := template.Must(template.ParseGlob(pattern))// We must define an implementation of the T2 template. First we clone// the drivers, then add a definition of T2 to the template name space.// 1. Clone the helper set to create a new name space from which to run them.first, err := drivers.Clone()if err != nil {
        log.Fatal("cloning helpers: ", err)}// 2. Define T2, version A, and parse it._, err = first.Parse("{{define `T2`}}T2, version A{{end}}")if err != nil {
        log.Fatal("parsing T2: ", err)}// Now repeat the whole thing, using a different version of T2.// 1. Clone the drivers.second, err := drivers.Clone()if err != nil {
        log.Fatal("cloning drivers: ", err)}// 2. Define T2, version B, and parse it._, err = second.Parse("{{define `T2`}}T2, version B{{end}}")if err != nil {
        log.Fatal("parsing T2: ", err)}// Execute the templates in the reverse order to verify the// first is unaffected by the second.err = second.ExecuteTemplate(os.Stdout, "T0.tmpl", "second")if err != nil {
        log.Fatalf("second execution: %s", err)}err = first.ExecuteTemplate(os.Stdout, "T0.tmpl", "first")if err != nil {
        log.Fatalf("first: execution: %s", err)}

輸出:

T0 (second version) invokes T1: (T1 invokes T2: (T2, version B))T0 (first version) invokes T1: (T1 invokes T2: (T2, version A))

func Must

func Must(t *Template, err error) *Template

Must 必須是一個幫助函數(shù),如果錯誤不為零,它會將函數(shù)調(diào)用返回 (*Template,error) 并發(fā)生混亂。它旨在用于變量初始化,如

var t = template.Must(template.New("name").Parse("html"))

func New

func New(name string) *Template

新分配給定名稱的新 HTML 模板。

func ParseFiles

func ParseFiles(filenames ...string) (*Template, error)

ParseFiles 創(chuàng)建一個新的模板并從命名文件中解析模板定義。返回的模板名稱將具有第一個文件的(基本)名稱和(已解析)內(nèi)容。必須至少有一個文件。如果發(fā)生錯誤,解析將停止,返回的* Template將為零。

當在不同的目錄中分析具有相同名稱的多個文件時,提到的最后一個將是結(jié)果。例如,ParseFiles("a/foo", "b/foo") 存儲"b/foo" 作為名為“foo”的模板,而“a / foo”不可用。

func ParseGlob

func ParseGlob(pattern string) (*Template, error)

ParseGlob創(chuàng)建一個新的模板并分析模式標識的文件中的模板定義,該文件必須至少匹配一個文件。返回的模板將具有與該模式匹配的第一個文件的(基本)名稱和(已分析)內(nèi)容。ParseGlob相當于使用模式匹配的文件列表調(diào)用ParseFiles。

當在不同的目錄中分析具有相同名稱的多個文件時,提到的最后一個將是結(jié)果。

func (*Template) AddParseTree

func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error)

AddParseTree 使用名稱和分析樹創(chuàng)建一個新模板并將其與 t 關(guān)聯(lián)。

如果 t 或任何關(guān)聯(lián)的模板已經(jīng)被執(zhí)行,它會返回一個錯誤。

func (*Template) Clone

func (t *Template) Clone() (*Template, error)

克隆返回模板的副本,包括所有關(guān)聯(lián)的模板。實際表示不會被復制,但是相關(guān)模板的名稱空間是,因此對副本中的分析進一步調(diào)用會將模板添加到副本,但不會添加到原始模板??梢允褂每寺碇苽渫ㄓ媚0?,并在制作克隆后通過添加變體來將它們與其他模板的變體定義一起使用。

如果 t 已經(jīng)執(zhí)行,它會返回一個錯誤。

func (*Template) DefinedTemplates

func (t *Template) DefinedTemplates() string

DefinedTemplates 返回一個字符串,列出定義的模板,以字符串“; defined templates are: ”為前綴。如果沒有,則返回空字符串。用于生成錯誤消息。

func (*Template) Delims

func (t *Template) Delims(left, right string) *Template

Delims 將動作分隔符設(shè)置為指定的字符串,以便在隨后調(diào)用 Parse, ParseFiles 或 ParseGlob 時使用。嵌套模板定義將繼承這些設(shè)置。一個空的分隔符表示相應(yīng)的默認值:{{或}}。返回值是模板,因此可以將調(diào)用鏈接起來。

func (*Template) Execute

func (t *Template) Execute(wr io.Writer, data interface{}) error

執(zhí)行將解析的模板應(yīng)用于指定的數(shù)據(jù)對象,將輸出寫入 wr 。如果執(zhí)行模板或?qū)懭肫漭敵鰰r發(fā)生錯誤,則執(zhí)行停止,但部分結(jié)果可能已寫入輸出寫入器。模板可以并行安全地執(zhí)行,但如果并行執(zhí)行共享 Writer ,輸出可能會交錯。

func (*Template) ExecuteTemplate

func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error

ExecuteTemplate 將與具有給定名稱的 t 關(guān)聯(lián)的模板應(yīng)用于指定的數(shù)據(jù)對象,并將輸出寫入 wr 。如果執(zhí)行模板或?qū)懭肫漭敵鰰r發(fā)生錯誤,則執(zhí)行停止,但部分結(jié)果可能已寫入輸出寫入器。模板可以并行安全地執(zhí)行,但如果并行執(zhí)行共享 Writer ,輸出可能會交錯。

func (*Template) Funcs

func (t *Template) Funcs(funcMap FuncMap) *Template

Funcs 將參數(shù)圖的元素添加到模板的功能圖中。它必須在解析模板之前調(diào)用。如果映射中的值不是具有適當返回類型的函數(shù),則會發(fā)生混亂。但是,覆蓋地圖的元素是合法的。返回值是模板,因此可以將調(diào)用鏈接起來。

func (*Template) Lookup

func (t *Template) Lookup(name string) *Template

Lookup 返回與 t 關(guān)聯(lián)的給定名稱的模板,如果沒有這樣的模板,則返回 nil。

func (*Template) Name

func (t *Template) Name() string

名稱返回模板的名稱。

func (*Template) New

func (t *Template) New(name string) *Template

新分配一個新的 HTML 模板與給定的和相同的分隔符相關(guān)聯(lián)。該關(guān)聯(lián)是可傳遞的,它允許一個模板通過 {{template}} 動作調(diào)用另一個模板。

func (*Template) Option

func (t *Template) Option(opt ...string) *Template

選項為模板設(shè)置選項。選項由字符串描述,可以是簡單字符串或 "key=value"。選項字符串中最多只能有一個等號。如果選項字符串無法識別或無效,則選項會出現(xiàn)混亂。

已知選項:

missingkey:如果地圖使用地圖中不存在的鍵索引,則控制執(zhí)行過程中的行為。

"missingkey=default" or "missingkey=invalid"
	The default behavior: Do nothing and continue execution.
	If printed, the result of the index operation is the string"<no value>"."missingkey=zero"
	The operation returns the zero value for the map type's element."missingkey=error"
	Execution stops immediately with an error.

func (*Template) Parse

func (t *Template) Parse(text string) (*Template, error)

解析將文本解析為t的模板體。文本中的命名模板定義 ({{define ...}} 或 {{block ...}}語句) 定義了與 t 關(guān)聯(lián)的附加模板,并從 t 本身的定義中刪除。

在第一次使用“執(zhí)行”或任何相關(guān)模板之前,可以在連續(xù)調(diào)用 Parse 時重新定義模板。包含僅包含空格和注釋的主體的模板定義被視為空白,并且不會替換現(xiàn)有模板的主體。這允許使用 Parse 添加新的命名模板定義而不覆蓋主模板主體。

func (*Template) ParseFiles

func (t *Template) ParseFiles(filenames ...string) (*Template, error)

ParseFiles 解析命名文件并將生成的模板與 t 關(guān)聯(lián)。如果發(fā)生錯誤,解析將停止并且返回的模板為零;否則是 t 。必須至少有一個文件。

當在不同的目錄中分析具有相同名稱的多個文件時,提到的最后一個將是結(jié)果。

如果t或任何關(guān)聯(lián)的模板已經(jīng)執(zhí)行,則 ParseFiles 將返回一個錯誤。

func (*Template) ParseGlob

func (t *Template) ParseGlob(pattern string) (*Template, error)

ParseGlob 解析由模式標識的文件中的模板定義,并將生成的模板與 t 關(guān)聯(lián)。該模式由 filepath.Glob 處理,并且必須至少匹配一個文件。ParseGlob 相當于使用模式匹配的文件列表調(diào)用 t.ParseFiles。

當在不同的目錄中分析具有相同名稱的多個文件時,提到的最后一個將是結(jié)果。

如果 t 或任何關(guān)聯(lián)的模板已被執(zhí)行,則ParseGlob 將返回錯誤。

func (*Template) Templates

func (t *Template) Templates() []*Template

模板返回與t關(guān)聯(lián)的模板的一部分,包括 t 本身。

type URL

URL 封裝了已知的安全 URL 或 URL 子字符串(請參閱RFC 3986)。類似于javascript:checkThatFormNotEditedBeforeLeavingPage()受信任源的 URL 應(yīng)該放在頁面中,但默認情況下動態(tài)javascript:URL 會被過濾掉,因為它們是一個經(jīng)常被利用的注入向量。

使用這種類型會帶來安全風險:封裝的內(nèi)容應(yīng)該來自可信來源,因為它將逐字包含在模板輸出中。

type URL string
Previous article: Next article: