Response
JSON
ctx.JSON是Gin中用于返回JSON数据的常用方法。它会将数据结构(如结构体、切片、字典)序列化成JSON格式,并设置正确的Content-Type为application/json。
此方法会自动对JSON数据进行转义,确保JSON数据的安全性。例如,对HTML特殊字符进行转义。
r.GET("/test", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"code": 0,
"msg": "OK",
"text": "<h1>This is a response</h1>",
})
})
如上,会对特殊字<、>等进行转义(Unicode码),最终响应的结果为:
{"code":0,"msg":"OK","text":"\u003ch1\u003eThis is a response\u003c/h1\u003e"}
PureJSON
ctx.PureJSON是一个更低层次的方法,它将数据直接序列化成JSON格式并返回,不会自动处理特殊字符的转义。
r.GET("/test", func(ctx *gin.Context) {
ctx.PureJSON(http.StatusOK, gin.H{
"code": 0,
"msg": "OK",
"text": "<h1>This is a response</h1>",
})
})
// {"code":0,"msg":"OK","text":"<h1>This is a response</h1>"}
相比之下,ctx.JSON是更安全的选择,而在使用ctx.PureJSON时,确保数据已经被正确处理,以免潜在的安全问题。
Protobuf
使用ctx.ProtoBuf方法可响应Protobuf格式,并将Content-Type设置为application/x-protobuf。
但由于其响应的是二进制文件,且浏览器无法解析application/x-protobuf的内容,如果直接请求通常表现为乱码。因此通常需要一个中间层服务来做请求转发,将解析后的数据通过接口提供给前端。
- user.proto
- main.go
- app.js
- package.json
syntax = "proto3";
option go_package = "/;proto";
message User {
int32 uid = 1;
string name = 2;
int32 age = 3;
string gender = 4;
repeated string languages = 5;
}
package main
import (
"basic4/proto"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/test", func(ctx *gin.Context) {
user := &proto.User{
Uid: 1,
Name: "wxm",
Age: 20,
Gender: "male",
Languages: []string{
"Go",
"JavaScript",
},
}
ctx.ProtoBuf(http.StatusOK, user)
})
r.Run()
}
const express = require('express')
const protobuf = require('protobufjs')
const path = require('path')
const axios = require('axios')
const app = express()
app.get('/test', async (req, res) => {
// 加载proto文件
const proto = await protobuf.load(
path.resolve(__dirname, '../proto/user.proto')
)
// 创建User实例
const User = proto.lookupType('User')
// 请求
const result = await axios({
url: 'http://localhost:8080/test',
method: 'get',
responseType: 'arraybuffer'
})
// 解析为json
const user = User.decode(result.data)
// 响应给前端
res.json(user)
})
app.listen(3000, () => {
console.log('Server is running on port 3000')
})
{
"name": "client",
"version": "1.0.0",
"main": "app.js",
"scripts": {
"dev": "nodemon ./app.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"axios": "^1.7.4",
"express": "^4.19.2",
"protobufjs": "^7.3.2"
},
"devDependencies": {
"nodemon": "^3.1.4"
}
}