使用html/template渲染Slack邮件链接时出现ZgotmplZ问题求助
解决Go模板渲染Slack Mailto链接时出现ZgotmplZ的问题
问题原因
Go的html/template会自动进行上下文感知的安全转义,当模板识别到<mailto:...>属于URL上下文时,会对未标记为安全的字符串内容进行拦截,替换为ZgotmplZ以防范注入风险。你的场景中邮箱地址来自可信源,可通过指定安全类型豁免过滤。
解决方案
方案1:改用text/template
Slack消息格式不属于HTML范畴,无需HTML转义,直接使用text/template即可规避自动安全过滤:
package main import ( "bytes" "fmt" "text/template" ) func main() { emailTemplate := `<mailto:{{.user_email }}|{{.user_email}}> has confirmed his email` tmpl, err := template.New("emailTemplate").Parse(emailTemplate) if err != nil { panic(err) } data := map[string]interface{}{ "user_email": "john.doe@gmail.com", } var buf bytes.Buffer err = tmpl.Execute(&buf, data) if err != nil { panic(err) } fmt.Println(buf.String()) }
方案2:在html/template中使用safeURL函数
通过template.FuncMap注册safeURL函数,将邮箱标记为安全的URL内容:
package main import ( "bytes" "fmt" "html/template" ) func main() { emailTemplate := `<mailto:{{.user_email | safeURL}}|{{.user_email | safeURL}}> has confirmed his email` tmpl, err := template.New("emailTemplate").Funcs(template.FuncMap{ "safeURL": template.URL, }).Parse(emailTemplate) if err != nil { panic(err) } data := map[string]interface{}{ "user_email": "john.doe@gmail.com", } var buf bytes.Buffer err = tmpl.Execute(&buf, data) if err != nil { panic(err) } fmt.Println(buf.String()) }
方案3:将邮箱包装为template.URL类型
传递数据时,把邮箱值包装成template.URL类型,明确告知模板该内容为安全URL:
package main import ( "bytes" "fmt" "html/template" ) func main() { emailTemplate := `<mailto:{{.user_email}}|{{.user_email}}> has confirmed his email` tmpl, err := template.New("emailTemplate").Parse(emailTemplate) if err != nil { panic(err) } data := map[string]interface{}{ "user_email": template.URL("john.doe@gmail.com"), } var buf bytes.Buffer err = tmpl.Execute(&buf, data) if err != nil { panic(err) } fmt.Println(buf.String()) }
以上三种方法均可生成预期输出:<mailto:john.doe@gmail.com|john.doe@gmail.com> has confirmed his email,可根据实际场景选择使用。
内容的提问来源于stack exchange,提问作者PRATHEESH PC
相关产品推荐
相关产品推荐

