zoukankan      html  css  js  c++  java
  • text与html模板的区别

    text与html模板的区别

    html/template针对的是需要返回HTML内容的场景,在模板渲染过程中会对一些有风险的内容进行转义,以此来防范跨站脚本攻击。

    image-20211111224009410

    image-20211111225242590

    一、text/template

    package main
    
    import (
    	"fmt"
    	"net/http"
    	"text/template" // 导入text模板
    )
    
    
    func xss(w http.ResponseWriter, r *http.Request)  {
    	// 定义模板
    
    	// 解析模板
    	// 自定默认的标识符
    	t, err := template.ParseFiles("./xss.tmpl")
    	if err != nil{
    		fmt.Printf("parse tmpl falied err:%#v\n", err)
    	}
    	// 渲染模板
    	str := "<script>alert(123);</script>" // text会被解析为html标记语言
    	//str := "<a href='www.baidu.com'>百度</a>"
    	err = t.Execute(w, str)
    
    	if err != nil{
    		fmt.Printf("execute template failed  err: %#v", err)
    		return
    	}
    }
    
    func main() {
    	http.HandleFunc("/customDefined", customDefined)
    	http.HandleFunc("/xss", xss)
    	err := http.ListenAndServe(":9999", nil)
    	if err != nil{
    		fmt.Printf("http server run faild err:%#V", err)
    	}
    
    }
    
    
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Hello Template</title>
    </head>
    <body>
    <p>用户的评论是:{{.}}</p>
    </body>
    </html>
    

    image-20211111225438672

    二、html/tempalte

    package main
    
    import (
    	"fmt"
    	"html/template" // 导入html模板
    	"net/http"
    )
    
    
    func xss(w http.ResponseWriter, r *http.Request)  {
    	// 定义模板
    
    	// 解析模板
    	// 自定默认的标识符
    	t, err := template.ParseFiles("./xss.tmpl")
    	if err != nil{
    		fmt.Printf("parse tmpl falied err:%#v\n", err)
    	}
    	// 渲染模板
    	str := "<script>alert(123);</script>"  // 不会被解析html标记语言
    	//str := "<a href='www.baidu.com'>百度</a>"
    	err = t.Execute(w, str)
    
    	if err != nil{
    		fmt.Printf("execute template failed  err: %#v", err)
    		return
    	}
    }
    
    func main() {
    	http.HandleFunc("/customDefined", customDefined)
    	http.HandleFunc("/xss", xss)
    	err := http.ListenAndServe(":9999", nil)
    	if err != nil{
    		fmt.Printf("http server run faild err:%#V", err)
    	}
    
    }
    
    
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Hello Template</title>
    </head>
    <body>
    <p>用户的评论是:{{.}}</p>
    </body>
    </html>
    

    image-20211111225723034

    这个时候传入一段JS代码并使用html/template去渲染该文件,会在页面上显示出转义后的JS内容。用户的评论是:<script>alert(123);</script> 这就是html/template为我们做的事。

    但是在某些场景下,我们如果相信用户输入的内容,不想转义的话,可以自行编写一个safe函数,手动返回一个template.HTML类型的内容。示例如下:

    package main
    
    import (
    	"fmt"
    	"html/template"
    	"net/http"
    )
    
    func xssSafe(w http.ResponseWriter, r *http.Request) {
    	// 定义模板
    
    	// 解析模板
    	// 自定默认的标识符
    	t, err := template.New("xss.tmpl").Funcs(
    		template.FuncMap{
    			"safe": func(s string) template.HTML {
    				return template.HTML(s)
    			},
    		},
    	).ParseFiles("./xss.tmpl")
    	if err != nil {
    		fmt.Printf("parse tmpl falied err:%#v\n", err)
    	}
    	// 渲染模板
    	str1 := "<script>alert(123);</script>"
    	str2 := "<a href='https://www.cnblogs.com/randysun/'>博客</a>"
    	err = t.Execute(w, map[string]string{
    		"str1": str1,
    		"str2": str2,
    	})
    
    	if err != nil {
    		fmt.Printf("execute template failed  err: %#v", err)
    		return
    	}
    }
    func main() {
    	http.HandleFunc("/xssSafe", xssSafe)
    	err := http.ListenAndServe(":9999", nil)
    	if err != nil {
    		fmt.Printf("http server run faild err:%#V", err)
    	}
    }
    
    
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Hello Template</title>
    </head>
    <body>
    <p>用户的评论是:{{.str1 | safe}}</p>
    <p>博客:{{.str2 | safe}}</p>
    </body>
    </html>
    

    这样我们只需要在模板文件不需要转义的内容后面使用我们定义好的safe函数就可以了。

    {{ . | safe }}
    

    image-20211111231622732

    image-20211111231611918

    在当下的阶段,必将由程序员来主导,甚至比以往更甚。
  • 相关阅读:
    VUE调用函数,以及event的讲解
    VUE双向绑定,以及表达式自增
    使用VUE的准备工作,以及显示文本
    MVC中VUE的学习
    Redis
    C# form表单提交enctype="multipart/form-data" 与 enctype="application/x-www-form-urlencoded" 两者之间的区别
    C# 导入导出
    文件压缩,解压缩
    [vue-router] Duplicate named routes definition: { name: "Front", path: "/home/front" }
    * @/components/widget/AddBands in ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/components/pages/Brands.vue
  • 原文地址:https://www.cnblogs.com/randysun/p/15622060.html
Copyright © 2011-2022 走看看