Golang GinWeb框架5-XML/JSON/YAML/ProtoBuf等渲染
簡(jiǎn)介
本文接著上文(Golang GinWeb框架5-綁定請(qǐng)求字符串/URI/請(qǐng)求頭/復(fù)選框/表單類型)繼續(xù)探索GinWeb框架。
XML,JSON,YAML,ProtoBuf等渲染
- package main
- import (
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/testdata/protoexample"
- "net/http"
- )
- func main() {
- r := gin.Default()
- // gin.H is a shortcut for map[string]interface{}
- // gin.H對(duì)象是一個(gè)map映射,鍵名為字符串類型, 鍵值是接口,所以可以傳遞所有的類型
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
- r.GET("/moreJSON", func(c *gin.Context) {
- // You also can use a struct
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // Note that msg.Name becomes "user" in the JSON
- // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
- //JSON serializes the given struct as JSON into the response body. It also sets the Content-Type as "application/json".
- //JSON方法將給定的結(jié)構(gòu)序列化為JSON到響應(yīng)體, 并設(shè)置內(nèi)容類型Content-Type為:"application/json"
- c.JSON(http.StatusOK, msg)
- })
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
- //Protocol buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data.
- //Protocol buffers(簡(jiǎn)稱ProtoBuf)是來(lái)自Google的一個(gè)跨語(yǔ)言,跨平臺(tái),用于將結(jié)構(gòu)化數(shù)據(jù)序列化的可擴(kuò)展機(jī)制,
- //詳見(jiàn):https://developers.google.com/protocol-buffers
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // The specific definition of protobuf is written in the testdata/protoexample file.
- // 使用protoexample.Test這個(gè)特別的protobuf結(jié)構(gòu)來(lái)定義測(cè)試數(shù)據(jù)
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // Note that data becomes binary data in the response //將data序列化為二進(jìn)制的響應(yīng)數(shù)據(jù)
- // Will output protoexample.Test protobuf serialized data
- // ProtoBuf serializes the given struct as ProtoBuf into the response body.
- // ProtoBuf方法將給定的結(jié)構(gòu)序列化為ProtoBuf響應(yīng)體
- c.ProtoBuf(http.StatusOK, data)
- })
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
- }
- /*
- 模擬測(cè)試
- curl http://localhost:8080/someJSON
- {"message":"hey","status":200}
- curl http://localhost:8080/moreJSON
- {"user":"Lena","Message":"hey","Number":123}
- curl http://localhost:8080/someXML
- <map><message>hey</message><status>200</status></map>
- curl http://localhost:8080/someYAML
- message: hey
- status: 200
- curl http://localhost:8080/someProtoBuf
- test
- */
安全的JSOn
使用SecureJSON方法保護(hù)Json不被劫持, 如果響應(yīng)體是一個(gè)數(shù)組, 該方法會(huì)默認(rèn)添加`while(1)`前綴到響應(yīng)頭, 這樣的死循環(huán)可以防止后面的代碼被惡意執(zhí)行, 也可以自定義安全JSON的前綴.
- package main
- import (
- "github.com/gin-gonic/gin"
- "net/http"
- )
- func main() {
- r := gin.Default()
- // You can also use your own secure json prefix
- // 你也可以自定義安全Json的前綴
- r.SecureJsonPrefix(")]}',\n")
- //使用SecureJSON方法保護(hù)Json不被劫持, 如果響應(yīng)體是一個(gè)數(shù)組, 該方法會(huì)默認(rèn)添加`while(1)`前綴到響應(yīng)頭, 這樣的死循環(huán)可以防止后面的代碼被惡意執(zhí)行, 也可以自定義安全JSON的前綴.
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
- //names := map[string]string{
- // "hello": "world",
- //}
- // Will output : while(1);["lena","austin","foo"]
- c.SecureJSON(http.StatusOK, names)
- })
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
- }
- /*
- 模擬請(qǐng)求:curl http://localhost:8080/someJSON
- )]}',
- ["lena","austin","foo"]%
- */
JSONP
使用JSONP可以實(shí)現(xiàn)跨域請(qǐng)求數(shù)據(jù), 如果請(qǐng)求中有查詢字符串參數(shù)callback, 則將返回?cái)?shù)據(jù)作為參數(shù)傳遞給callback值(前端函數(shù)名),整體作為一個(gè)響應(yīng)體,返回給前端.
JSONP是服務(wù)器與客戶端跨源通信的常用方法. 最大特點(diǎn)就是簡(jiǎn)單適用, 老式瀏覽器全部支持, 服務(wù)器改造非常小, 它的基本思想是: 網(wǎng)頁(yè)通過(guò)添加一個(gè)<script>元素, 向服務(wù)器請(qǐng)求JSON數(shù)據(jù), 這種做法不受同源政策限制, 服務(wù)器收到請(qǐng)求后, 將數(shù)據(jù)放在一個(gè)指定名字的回調(diào)函數(shù)里傳回來(lái), 這樣, 前端可以完成一次前端函數(shù)的調(diào)用, 而參數(shù)是后端返回的數(shù)據(jù).
注意: 這種方式存在被劫持的風(fēng)險(xiǎn)
- package main
- import (
- "github.com/gin-gonic/gin"
- "net/http"
- )
- func main() {
- r := gin.Default()
- r.GET("/JSONP", func(c *gin.Context) {
- data := gin.H{
- "foo": "bar",
- }
- //callback is x
- // Will output : x({\"foo\":\"bar\"})
- // 使用JSONP可以實(shí)現(xiàn)跨域請(qǐng)求數(shù)據(jù), 如果請(qǐng)求中有查詢字符串參數(shù)callback, 則將返回?cái)?shù)據(jù)作為參數(shù)傳遞給callback值(前端函數(shù)名),整體作為一個(gè)響應(yīng)體,返回給前端
- //JSONP是服務(wù)器與客戶端跨源通信的常用方法。最大特點(diǎn)就是簡(jiǎn)單適用,老式瀏覽器全部支持,服務(wù)器改造非常小。
- //它的基本思想是,網(wǎng)頁(yè)通過(guò)添加一個(gè)<script>元素,向服務(wù)器請(qǐng)求JSON數(shù)據(jù),這種做法不受同源政策限制;服務(wù)器收到請(qǐng)求后,將數(shù)據(jù)放在一個(gè)指定名字的回調(diào)函數(shù)里傳回來(lái)
- c.JSONP(http.StatusOK, data)
- })
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
- // 模擬客戶端,請(qǐng)求參數(shù)中有callback參數(shù),值為x(前端函數(shù)名),最后響應(yīng)內(nèi)容為x("foo":"bar")
- // curl http://127.0.0.1:8080/JSONP?callback=x
- }
AsciiJSON
使用ASCII編碼, 將非ASCII的字符進(jìn)行轉(zhuǎn)義和編碼, 生成純ASCII編碼的JSON
- package main
- import (
- "github.com/gin-gonic/gin"
- "net/http"
- )
- func main() {
- r := gin.Default()
- r.GET("/someJSON", func(c *gin.Context) {
- data := gin.H{
- "lang": "GO語(yǔ)言",
- "tag": "<br>",
- }
- // 輸出結(jié)果 : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
- // AsciiJSON方法返回帶有Unicode編碼和轉(zhuǎn)義組成的純ASCII字符串
- c.AsciiJSON(http.StatusOK, data)
- })
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
- }
- /*
- 模擬請(qǐng)求:curl http://localhost:8080/someJSON
- */
不帶轉(zhuǎn)義的原始JSON
通常, JSON會(huì)將特殊的HTML字符轉(zhuǎn)化為他們的unicode編碼, 如標(biāo)簽`<`轉(zhuǎn)為`\u003c` 使用PureJSON方法可以得到原始不做轉(zhuǎn)義的字符串.
注意: 該方法至少需要Go版本1.6以上
- package main
- import "github.com/gin-gonic/gin"
- func main() {
- r := gin.Default()
- // Serves unicode entities
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "<b>Hello, world!</b>",
- })
- })
- // Serves literal characters
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "<b>Hello, world!</b>",
- })
- })
- // listen and serve on 0.0.0.0:8080
- r.Run(":8080")
- }
- /*
- 模擬請(qǐng)求,得到將HTML標(biāo)簽轉(zhuǎn)義后的JSON字符串
- curl http://localhost:8080/json
- {"html":"\u003cb\u003eHello, world!\u003c/b\u003e"}
- 得到原始JSON字符串
- curl http://localhost:8080/purejson
- {"html":"<b>Hello, world!</b>"}
- */
參考文檔
Gin官方倉(cāng)庫(kù):https://github.com/gin-gonic/gin