golang-标准库(html/template)

这个标准库,是go实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出。简单说就是对html,css,javascript进行安全转换;例如对html中的

这个标签的特殊字符<>进行转换。还有用于生成安全的html模版代码的方法。

与之相似还有另一个包 text/template,只是前者解析html,后者解析普通文本字符串而已。

先看几个简单html片段的转义方法:

func HTMLEscapeString(s string) string =》 返回s的HTML转义等价表示字符串。
func HTMLEscaper(args ...interface{}) string =》返回所有多个参数文本表示的HTML转义等价表示字符串
func HTMLEscape(w io.Writer, b []byte) =》向w中写入b的HTML转义等价表示

先认识一下常见的几个html转义字符

" " "
& & &
< < <
> > >
不断开空格(non-breaking space)    

 

下面看代码示例:

package main

import (
	"fmt"
	"html/template"
)

func main() {

	s := template.HTMLEscapeString("
hello
") fmt.Println(s) // 打印 <div>hello</div> s = template.HTMLEscaper("
","hello","
") fmt.Println(s) // 打印 <div>hello</div> // template.HTMLEscape() // 这个方法将html转义后的片段写入到w可写流,不再演示 }

再看几个对javascript代码转义的方法

func JSEscapeString(s string) string =》返回s的JavaScript转义等价表示字符串。
func JSEscaper(args ...interface{}) string =》返回多个参数文本表示的JavaScript转义等价表示字符串。
func JSEscape(w io.Writer, b []byte) =》向w中写入b的JavaScript转义等价表示。

下面看对javascript代码的转义示例:


func main() {

	s := template.JSEscapeString("var a = 'hello'")
	fmt.Println(s) // 打印 var a = \'hello\'

	s = template.JSEscaper("var"," a = ","'hello'")
	fmt.Println(s) // 打印 var a = \'hello\'

	// template.JSEscape() // 这个方法将javascript代码转义后的片段写入到w可写流,不再演示
}

下面看一个对url转义的方法:

func URLQueryEscaper(args ...interface{}) string =》返回多个参数文本表示的可以嵌入URL查询的转义等价表示字符串
package main

import (
	"fmt"
	"html"
	"html/template"
)

func main() {

	s := template.URLQueryEscaper("name=go&age=10")
	fmt.Println(s) // 打印 name%3Dgo%26age%3D10
	// 可以看到 URLQueryEscaper 方法是将字符转为其ASCII码表的值;= 的ASCII码为3D,这里跟html包的EscapeString有些不同,看下面一行代码:
	fmt.Println(html.EscapeString("name=go&age=10")) // 打印 name=go&age=10
	// html.EscapeString是将其特殊字符转为html特殊字符转义表对应的字符;= 为&
}

下面看templdate包提供的可生成安全的(防注入)html模版代码的方法

先看几个简单的方法:

func New(name string) *Template =》 新建名为name的一个模版
func (t *Template) Parse(src string) (*Template, error) =》 解析src为模版的内容
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error =》 解析name模版,将其应用到data数据上,解析后的结果写入到wr可写流
func (t *Template) Execute(wr io.Writer, data interface{}) error => 直接将数据应用到模版,没有模版名字。

下面看简单的代码示例:

package main

import (
	"html/template"
	"os"
)

func main() {
	// 创建一个模版,并解析内容;{{define "T"}} 意思是定义一个名为T的模版,必须用字符串抱起来,否则报错,
	// {{.}}为应用到模版上的数据,{{end}}表示模版解析结束,也必须要有;
	temp,_ := template.New("foo").Parse(`{{define "T"}} hello {{.}}{{end}}`)
	// 将数据应用到模版上,然后将内容输出到标准输出。
 	temp.ExecuteTemplate(os.Stdout,"T","
go
") // 打印 hello <div>go</div> // 可以看到,将{{.}}内容替换为了对应的html片段,同时html片段也进行了特殊字符的转义 // 直接创建一个模版 temp,_ := template.New("foo").Parse(`hello {{.}}`) // 将数据应用到模版上,然后将内容输出到标准输出。 temp.Execute(os.Stdout,"
go
") // 打印 hello <div>go</div> // 可以看到,将{{.}}内容替换为了对应的html片段,同时html片段也进行了特殊字符的转义 }

通过上面的例子,大致认识了自定义html模版的用法,下面看html模版的其它方法:

func (t *Template) ParseFiles(filenames ...string) (*Template, error) =》解析filenames指定的文件里的模板。如果发生错误,会停止解析并返回nil,否则返回(t, nil)。至少要提供一个文件。Parse方法直接传入字符串模版,ParseFiles从文件中读取,本质上没有区别。

到此,templdate包基本使用方法就算介绍完了,template包日常开发中也就用于生成一下html片段模版。用得不多。

你可能感兴趣的:(go,golang标准库)