gin响应
812字约3分钟
2025-02-15
gin提供了非常多的响应方法
例如 字符串、json、html等
json响应
现在大部分的前后端交互都是以json为主,所以gin中最常用的就是json响应
c.JSON(200, gin.H{
"code": 0,
"msg": "ok",
})
但是我们都会对其进行一番封装,例如标准响应格式 code,data,msg
前端可以判断code的值来确定操作是否成功
例如code=0为操作成功的状态码,非0值就是具体的错误码,这样可以方便定位错误
package res
import "github.com/gin-gonic/gin"
type Response struct {
Code int `json:"code"`
Data any `json:"data"`
Msg string `json:"msg"`
}
type Code int
const (
RoleErrCode Code = 1001
NetworkErrCode Code = 1002
)
var codeMap = map[Code]string{
RoleErrCode: "权限错误",
NetworkErrCode: "网络错误",
}
func init() {
// 可能是一个
}
func response(c *gin.Context, r Response) {
c.JSON(200, r)
}
func Ok(c *gin.Context, data any, msg string) {
response(c, Response{
Code: 0,
Data: data,
Msg: msg,
})
}
func OkWithData(c *gin.Context, data any) {
Ok(c, data, "成功")
}
func OkWithMsg(c *gin.Context, msg string) {
Ok(c, map[string]any{}, msg)
}
func Fail(c *gin.Context, code int, data any, msg string) {
response(c, Response{
Code: code,
Data: data,
Msg: msg,
})
}
func FailWithMsg(c *gin.Context, msg string) {
response(c, Response{
Code: 7,
Data: nil,
Msg: msg,
})
}
func FailWithCode(c *gin.Context, code Code) {
// 去找code对应的msg
msg, ok := codeMap[code]
if !ok {
msg = "未知错误"
}
response(c, Response{
Code: int(code),
Data: nil,
Msg: msg,
})
}
封装之后,使用
res.OkWithMsg(c, "登陆成功")
res.OkWithData(c, map[string]any{
"name": "阿哲",
})
res.FailWithMsg(c, "参数错误")
html响应
使用LoadHTMLGlob加载一个目录下的所有html文件
也可以使用LoadHTMLFiles加载单个html文件
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
// 加载模板 只有这里加载了模板,下面才能用
r.LoadHTMLGlob("templates/*")
//r.LoadHTMLFiles("templates/index.html")
r.GET("", func(c *gin.Context) {
c.HTML(200, "index.html", nil)
})
r.Run(":8080")
}
HTML的第三个参数是可以向HTML中传递数据
现在都是前后端分离的时代了,也很少使用后端返回模板了
c.HTML(200, "index.html", map[string]any{
"title": "这是网页标题",
})
html文件中使用
<title>{{.title}}</title>
关于部署:
- 前端单独部署,后端单独部署
- 前端打包之后,后端统一部署
响应文件
用于浏览器直接请求这个接口唤起下载
c.Header("Content-Type", "application/octet-stream") // 表示是文件流,唤起浏览器下载,一般设置了这个,就要设置文件名
c.Header("Content-Disposition", "attachment; filename=3.文件下载.go") // 用来指定下载下来的文件名
c.File("3.文件下载.go")
- 要设置Content-Type,唤起浏览器下载
- 只能是get请求
前端请求后端接口,然后唤起浏览器下载
c.Header("fileName", "xxx.png")
c.Header("msg", "文件下载成功")
c.File("uploads/12.png")
前端唤起浏览器下载的本质
<a href="文件地址" download="文件名">文件下载</a>
async downloadFile(row) {
this.$http({
method: 'post',
url: 'file/upload',
data:postData,
responseType: "blob"
}).then(res => {
const _res = res.data
let blob = new Blob([_res], {
type: 'application/png'
});
let downloadElement = document.createElement("a");
let href = window.URL.createObjectURL(blob); //创建下载的链接
downloadElement.href = href;
downloadElement.download = res.headers["fileName"]; //下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); //点击下载
document.body.removeChild(downloadElement); //下载完成移除元素
window.URL.revokeObjectURL(href); //释放掉blob对象
})}
静态文件
r.Static("static", "static") // 第一个参数是别名,第二个才是实际路径
r.StaticFile("abcd", "static/abc.txt")
注意
静态文件的路径,不能再被路由使用了