avoid auto escape in html template

2020-04-16 04:14发布

Trying to render HTML template with an URL. The problem is that the URL contains () in it, and those characters are escaped.

I tried to use template.URL("http://myurl.com/(data)/aaa.jpg") and also template.HTML("http://myurl.com/(data)/aaa.jpg") but it still escape brackets.

I'm using gin gonic.

router.GET("/test", func(c *gin.Context) {
    c.HTML(http.StatusOK, "test.tmpl", gin.H{
        "url": template.URL("http://myurl.com/(data)/aaa.jpg"),
        // "url": template.HTML("http://myurl.com/(data)/aaa.jpg"),
})

Template file :

<div>
  <img src="{{.url}}" />
</div>

final ouput :

<div>
  <img src="http://myurl.com/%28data%29/aaa.jpg"/>
</div>

1条回答
你好瞎i
2楼-- · 2020-04-16 04:55

Using a value of template.URL is perfectly enough.

What you see is not HTML encoding of the given URL, what you see is the URL encoding of the opening and closing parenthesis in the (data) part. That is perfectly ok. %28 is the encoding of '(' (28 is the hexa code for the opening parenthesis character), and %29 is the ')' character.

The url http://myurl.com/(data)/aaa.jpg and http://myurl.com/%28data%29/aaa.jpg are one and the same.

The purpose of the URL encoding is so that URLs and values included in URLs (e.g. form parameters) can be safely transmitted.

URL Encoding

URLs can only be sent over the Internet using the ASCII character-set.

Since URLs often contain characters outside the ASCII set, the URL has to be converted into a valid ASCII format.

URL encoding replaces unsafe ASCII characters with a "%" followed by two hexadecimal digits. URLs cannot contain spaces. URL encoding normally replaces a space with a plus (+) sign or with %20.

You can read more about URL encoding here: HTML URL Encoding Reference.

Testing it:

func rh(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, `<html><body>
<img src="http://localhost:8080/(data)/aaa.jpg">
<img src="http://localhost:8080/%28data%29/aaa.jpg">
</body></htm>`)
}

func imgh(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "aaa.jpg")
}

func main() {
    http.HandleFunc("/", rh)
    http.HandleFunc("/(data)/aaa.jpg", imgh)
    panic(http.ListenAndServe("localhost:8080", nil))
}

Now direct your browser to http://localhost:8080. It will display 2 images.

查看更多
登录 后发表回答