💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Baa Context Context是HTTP上下文的意思,封装了`输入`、`输出`,提供请求处理,结果响应,模板渲染等相关操作。 ## Request `c.Req` Request 中包含了所有的请求数据,是标准包中 `http.Request` 的封装,可以通过 `c.Req` 访问原生的请求结构。 ### URL参数 `func (c *Context) Posts() map[string]interface{}` 获取所有的POST 和 GET 数据,返回一个字典,字典的索引为表单字段的名称,值为字段的值,值如果只有一个则为 `string` 类型,值有多个则为 `[]string` 类型。 `func (c *Context) Querys() map[string]interface{}` 获取所有的 GET 数据,返回一个字典,字典的索引为表单字段的名称,值为字段的值,值如果只有一个则为 `string` 类型,值有多个则为 `[]string` 类型。 `func (c *Context) Query(name string) string` 根据 `name` 获取一个字段的值,返回 `string` 类型,包含 POST 和 GET 数据。 `func (c *Context) QueryStrings(name string) []string` 根据 `name` 获取一个字段的多个值,返回 `[]string` 类型。 `func (c *Context) QueryEscape(name string) string` 根据 `name` 获取一个字段的值,escapre编码后返回 `string` 类型。 `func (c *Context) QueryTrim(name string) string` 根据 `name` 获取一个字段的值,去除两端空白后返回 `string` 类型。 `func (c *Context) QueryBool(name string) bool` 根据 `name` 获取一个字段的值,并强制转化为 `bool` 类型 返回。 `func (c *Context) QueryFloat(name string) float64` 根据 `name` 获取一个字段的值,并强制转化为 `float64` 类型 返回。 `func (c *Context) QueryInt(name string) int` 根据 `name` 获取一个字段的值,并强制转化为 `int` 类型 返回。 `func (c *Context) QueryInt32(name string) int32` 根据 `name` 获取一个字段的值,并强制转化为 `int32` 类型 返回。 `func (c *Context) QueryInt64(name string) int64` 根据 `name` 获取一个字段的值,并强制转化为 `int64` 类型 返回。 ### 路由参数 `func (c *Context) Param(name string) string` 根据 `name` 获取一个路由参数的值,返回 `string` 类型。 `func (c *Context) Params() map[string]string` 返回所有的路由参数组成的字典,字典的索引是参数名称。 `func (c *Context) ParamBool(name string) bool` 根据 `name` 获取一个路由参数的值,并强制转化为 `bool` 类型 返回。 `func (c *Context) ParamFloat(name string) float64` 根据 `name` 获取一个路由参数的值,并强制转化为 `float64` 类型 返回。 `func (c *Context) ParamInt(name string) int` 根据 `name` 获取一个路由参数的值,并强制转化为 `int` 类型 返回。 `func (c *Context) ParamInt32(name string) int32` 根据 `name` 获取一个路由参数的值,并强制转化为 `int32` 类型 返回。 `func (c *Context) ParamInt64(name string) int64` 根据 `name` 获取一个路由参数的值,并强制转化为 `int64` 类型 返回。 ### Cookie `func (c *Context) GetCookie(name string) string` 根据 `name` 获取一个Cookie的值,返回 `string` 类型。 `func (c *Context) GetCookieBool(name string) bool` 根据 `name` 获取一个Cookie的值,并强制转化为 `bool` 类型 返回。 `func (c *Context) GetCookieFloat64(name string) float64` 根据 `name` 获取一个Cookie的值,并强制转化为 `float64` 类型 返回。 `func (c *Context) GetCookieInt(name string) int` 根据 `name` 获取一个Cookie的值,并强制转化为 `int` 类型 返回。 `func (c *Context) GetCookieInt32(name string) int32` 根据 `name` 获取一个Cookie的值,并强制转化为 `int32` 类型 返回。 `func (c *Context) GetCookieInt64(name string) int64` 根据 `name` 获取一个Cookie的值,并强制转化为 `int64` 类型 返回。 `func (c *Context) SetCookie(name string, value string, others ...interface{})` 设置 名称为 `name` 值为 `value` 的Cookie。 `setCookie` 还可以指定更多Cookie参数,通过可变长度的 `others` 参数可以依次指定: ``` SetCookie(<name>, <value>, <max age>, <path>, <domain>, <secure>, <http only>) ``` 使用姿势: ``` c.SetCookie("mykey", "myvalue") c.SetCookie("mykey", "myvalue", 3600) c.SetCookie("mykey", "myvalue", 3600, "/") c.SetCookie("mykey", "myvalue", 3600, "/", ".vodjk.com") c.SetCookie("mykey", "myvalue", 3600, "/", ".vodjk.com", true) c.SetCookie("mykey", "myvalue", 3600, "/", ".vodjk.com", true, true) ``` > 可变参数需依次指定,不能跳过中间的参数 ### 文件上传 `func (c *Context) GetFile(name string) (multipart.File, *multipart.FileHeader, error)` 通过 `multipart/form-data` 表单上传的文件,可以通过 `c.GetFile` 指定文件字段获得到文件结构 [multipart.File](https://godoc.org/mime/multipart#File) 和 [multipart.FileHeader](https://godoc.org/mime/multipart#FileHeader), 然后可以利用这些结构进行文件大小检测,文件类型检测,文件存储等。 举个栗子: ``` func Upload(c *baa.Context) { file, header, err := c.GetFile("file1") if err != nil { c.Error(errors.New("没有文件被上传")) return } defer file.Close() savedTo := "savedFile.jpg" newFile, err := os.Create(savedTo) if err != nil { c.Error(errors.New("文件创建失败")) return } defer newFile.Close() size, err := io.Copy(newFile, file) msg := fmt.Sprintf("fileName: %s, savedTo: %s, size: %d, err: %v", header.Filename, savedTo, size, err) fmt.Println(msg) c.String(200, msg) } ``` `func (c *Context) SaveToFile(name, savePath string) error` 快速保存指定的文件字段 `name` 到指定的路径 `savePath` 并返回 `nil` 或者 `error` 还是上面的例子,改一下: ``` func Upload2(c *baa.Context) { savedTo := "savedFile2.jpg" err := c.SaveToFile("file1", savedTo) if err != nil { c.Error(err) return } c.String(200, savedTo) } ``` ## Response `c.Resp` Response 中用于处理结果输出,是标准包中 `http.ResponseWriter` 的封装,可以通过 `c.Resp` 访问原生的接口。 ### 数据存储 `Context` 提供了临时存储可用于整个请求的生命周期中。 `func (c *Context) Set(key string, v interface{})` 根据 `key` 设置一个值 `v` 到 `Context` 存储中。 `func (c *Context) Get(key string) interface{}` 根据 `key` 从`Context`存储中获取一个值并返回。 `func (c *Context) Gets() map[string]interface{}` 获取`Context`中存储的所有值,返回由这些值组成的字典。 举个例子: ``` package main import ( "gopkg.in/baa.v1" ) func main() { app := baa.New() app.Get("/", func(c *baa.Context) { c.Set("mykey", "myvalue") }, func(c *baa.Context) { val := c.Get("mykey") fmt.Println(val) // myvalue c.String(200, val.(string)) }) app.Run(":1323") } ``` ### 内容输出 baa 提供了多种形式的内容输出。 `func (c *Context) String(code int, s string)` 设定输出的 http code 为 `code`,并输出一个字符串 `s`。 `func (c *Context) Text(code int, s []byte)` 设定输出的 http code 为 `code`,并输出一个字节切片 `s`。 `func (c *Context) JSON(code int, v interface{})` 设定输出的 http code 为 `code`,设定内容类型为 `application/json`, 把 结构 `v` 使用JSON编码后输出。 `func (c *Context) JSONP(code int, callback string, v interface{})` 设定输出的 http code 为 `code`,设定内容类型为 `application/json`, 把 结构 `v` 使用JSON编码,并结合 `callback`参数输出。 `func (c *Context) JSONString(v interface{}) (string, error)` 把 结构 `v` 使用JSON编码后返回。 `func (c *Context) XML(code int, v interface{})` 设定输出的 http code 为 `code`,设定内容类型为 `application/json`, 把 结构 `v` 使用XML编码后输出。 ## 有用的函数 `func (c *Context) Baa() *Baa` `func (c *Context) Body() *RequestBody` `func (c *Context) Break()` `func (c *Context) Error(err error)` `func (c *Context) Next()` `func (c *Context) NotFound()` `func (c *Context) IsAJAX() bool` `func (c *Context) IsMobile() bool` `func (c *Context) Redirect(code int, url string) error` `func (c *Context) Referer() string` `func (c *Context) RemoteAddr() string` `func (c *Context) URL(hasQuery bool) string` `func (c *Context) UserAgent() string` ## 模板渲染 baa 集成一个简单的模板渲染,使用Go标准库的 [template语法](https://godoc.org/html/template)。 baa 的模板渲染使用 `Context`存储 中的数据作为模板变量。 `func (c *Context) Fetch(tpl string) ([]byte, error)` 根据 `tpl` 模板文件路径,使用 `Context`存储中的数据,渲染模板并返回渲染后的内容。 `func (c *Context) Render(code int, tpl string)` 设定输出的 http code 为 `code`,设定内容类型为 `text/html`, 渲染模板 `tpl` 并直接输出。 > 内部就是调用的 `c.Fetch` 然后 把内容输出 `func (c *Context) HTML(code int, tpl string)` `c.Render`的一个别名,用起来更顺手。 举个例子: ``` package main import baa "gopkg.in/baa.v1" func main() { app := baa.New() app.Get("/", func(c *baa.Context) { c.Set("title", "this is title") c.Set("content", "this is content") c.HTML(200, "template/index.html") }) app.Run(":1323") } ``` ``` <!-- template/index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{{ .title }}</title> </head> <body> {{ .content}} </body> </html> ``` ### 模板语法 以下仅做简单介绍,完整文档请见官方 [html/template](https://godoc.org/html/template)。 * 模板语法以一对 `双大括号` 包裹 * 变量都是以 `.` 开始,`.` 代表所有数据组成的结构 * 结构体中的字段用 `.` 表示子集 #### 输出变量 ``` {{ .var }} {{ .user.id }} ``` #### 条件语句 ``` {{ if .show }} i want show! {{ else }} i was hidden {{ end }} ``` #### 循环语句 ``` {{ range .list }} {{ .id }} {{ .name }} {{ end }} ``` 如果循环体不是结构体,比如就是一个字符串数组,直接用 `.` 即可输出: ``` {{ range .strs }} {{ . }} {{ end }} ``` ### 模板接口 baa 中运行通过 `DI` 替换模板引擎,只要实现 `baa.Renderer` 接口即可。 Renderer ``` type Renderer interface { Render(w io.Writer, tpl string, data interface{}) error } ``` 渲染接口只有一个方法 `Render`,该方法 接收三个参数: #### w `io.Writer` 一个可写入的类型,用于写入渲染后的数据,这里其实就是 `c.Resp` 。 #### tpl `string` 模板文件路径 #### data `interface{}` 向模板传递的数据(模板变量),这里其实传递过来的就是 `c.Gets` 的结果,是一个 `map[string]interface{}` 类型。