fiber中Context对象的用法
CTX 结构表示保存 HTTP 请求和响应的上下文
用于请求查询字符串,参数,正文,HTTP 标头等方法
Context 对象的方法有:
AllParams:获取所有路由参数 Append:在响应标头中添加指定的字段和内容 Attachment:设置响应标头Content-Disposition的值为attachment App:返回*App引用 BaseURL:string,基本URL(protocol + host) BodyRaw:[]byte,原始请求body Body:根据Content-Encoding尝试从正文字节执行文件解压缩,如果没有发送Content-Encoding头将作为BodyRaw执行 BodyParser:将请求正文绑定到结构 ClearCookie:清除客户端 Cookie Cookie:设置Cookie Cookies:获取键为key的cookie值 CookieParser:将cookie绑定到结构,用法类似于BodyParser Download:下载文件,浏览器会提示用户下载 FormFile:获取指定字段上传的第一个文件 FormValue:获取指定字段的第一个值 Get:返回指定请求标头,大小写不敏感 GetReqHeaders:map[string][]string,返回请求标头 GetRespHeaders:map[string][]string,返回响应标头 GetRespHeader:返回指定响应标头,大小写不敏感 Hostname:string,返回请求头中的Host值 IP:string,返回请求的客户端 IP 地址 IPs:[]string,返回X-Forwarded-For请求中的IP地址数组 Is:判定请求的Content-Type是否是指定后缀 IsFromLocal:判定请求是否来自本地主机 JSON:将相应内容转换为json格式并将Content-Type设置为application/json Links:设置相应的Link标头值 Locals:用于存储限定于请求范围的变量,因此仅对与请求匹配的路由可用 Location:设置响应Location标头值 Method:string,获取请求的方式 MultipartForm:解析表单所有字段及上传文件内容(以二进制形式) Next:error,执行堆栈中与当前路由匹配的下一个方法 OriginalURL:string,返回原始请求的URL(不含域名及之前的部分) Params:获取路由参数 ParamsInt:从路由参数中获取一个整数 Params(key string) (int, error) 从路由参数中获取一个整数 如果参数不在请求中,返回 0 如果参数不是一个数字,返回 0 和一个错误 Path:string,返回请求的文件路径(不含?及之后的部分) Protocol:string,返回请求的协议(http或https) Queries:返回所有查询字符串解析后的map Queries() map[string]string Query:获取查询字符串的指定参数值 Query(key string, defaultValue ...string) string 获取查询字符串的指定参数值 衍生的方法,可以自动将值转换为指定的类型 QueryBool(key string, defaultValue ...bool) bool QueryFloat(key string, defaultValue ...float64) float64 QueryInt(key string, defaultValue ...int) int QueryParser:将查询参数绑定到结构,用法类似于BodyParser Range:接受一个表示大小的数字,返回一个包含该类型和一个范围切片的结构 Redirect:重定向 Redirect(location string, status ...int) error status不传值默认为302 Render:模板渲染 SaveFile:将上传的文件保存到磁盘 Secure:bool,是否使用https协议,等同于c.Protocol() == "https" Send:设置 HTTP 响应体 在此基础上还拓展了两个方法用于类型断言 SendString(body string) error SendStream(stream io.Reader, size ...int) error SendFile:从给定的路径传输文件,会自动根据文件扩展名设置 Content-Type SendStatus:当响应正文为空,设置状态码和状态消息 Set:设置响应的 HTTP 标头字段 Set(key string, val string) Status:设置响应的 HTTP 状态,返回一个上下文,可以实现链式调用 Subdomains:返回请求的域名中的子域的字符串片断 Type:将Content-Type头设置为指定的拓展名对应的 MIME Vary:将给定的值追加到Vary响应头中,允许一次传递多个值 Write:采用 Writer 接口向响应主体中追加内容 Writef:以追加的方式将格式化内容输出到响应主体中 c.Writef("Hello, %s", "world") 类似于fmt.Printf() WriteString:以追加的方式将字符串输出到响应主体中
AllParams
获取所有路由参数
AllParams() map[string]string
app.Get("/:user/:id", CallBack)
fmt.Println(c.AllParams())
app.Listen(":3000")
访问:http://127.0.0.1:3000/demo/666
打印:map[id:666 user:demo]
Append
在响应标头中添加指定的字段和内容
Append(key string, values ...string)
c.Append("demo-test", "value")
// Demo-Test:value
// 首字母转换大写,短横后第一个字母大写
// 如果key中存在中文,则该命令不生效
c.Append("demo-test", "value1","value2","value3")
// Demo-Test:value1,value2,value3
Attachment
设置响应 Content-Disposition 标头值为 attachment,会弹出下载对话框
Attachment(filename ...string)
c.Attachment()
// 设置响应标头:Content-Disposition:attachment
// 将当前页面显示内容作为附件下载
c.Attachment("./upload/images/logo.png")
// 设置响应标头:Content-Disposition:attachment; filename=""logo.png"
// 指定文件作为附件下载
BodyParser
将请求正文绑定到结构,仅支持 POST 且 content-type 值为以下之一的请求
application/json
application/xml
application/x-www-form-urlencoded
multipart/form-data
BodyParser(out interface{}) error
type Person struct {
Name string `json:"name" xml:"name" form:"name"`
Pass string `json:"pass" xml:"pass" form:"pass"`
}
app.Post("/", func(c *fiber.Ctx) error {
p := new(Person)
if err := c.BodyParser(p); err != nil {
return err
}
log.Println(p.Name) // john
log.Println(p.Pass) // doe
})
//使用以下curl命令运行测试
// curl -X POST -H "Content-Type: application/json" --data "{\"name\":\"john\",\"pass\":\"doe\"}" localhost:3000
// curl -X POST -H "Content-Type: application/xml" --data "<login><name>john</name><pass>doe</pass></login>" localhost:3000
// curl -X POST -H "Content-Type: application/x-www-form-urlencoded" --data "name=john&pass=doe" localhost:3000
// curl -X POST -F name=john -F pass=doe http://localhost:3000
// curl -X POST "http://localhost:3000/?name=john&pass=doe"
ClearCookie
清除客户端 Cookie
ClearCookie(key ...string)
传入一个或多个 key 会清除指定的 key,不传入任何 key 值会清除所有 Cookie
Cookie
设置 Cookie
Cookie(cookie *Cookie)
type Cookie struct {
Name string `json:"name"`
Value string `json:"value"`
Path string `json:"path"`
Domain string `json:"domain"`
MaxAge int `json:"max_age"`
Expires time.Time `json:"expires"`
Secure bool `json:"secure"`
HTTPOnly bool `json:"http_only"`
SameSite string `json:"same_site"`
}
app.Get("/", func(c *fiber.Ctx) error {
cookie := new(fiber.Cookie)
cookie.Name = "john"
cookie.Value = "doe"
cookie.Expires = time.Now().Add(24 * time.Hour)
c.Cookie(cookie)
})
Cookies
获取键为 key 的 cookie 值
Cookies(key string, defaultValue ...string) string
第二个参数可选,表示如果 key 键不存在将返回的值
Download
将文件作为 attachment 从路径传输,浏览器会弹出下载对话框
Download(file string, filename ...string) error
可选参数 filename 指定下载文件名
FormFile
获取指定字段的第一个文件
FormFile(key string) (*multipart.FileHeader, error)
app.Post("/", func(c *fiber.Ctx) error {
file, err := c.FormFile("document")
c.SaveFile(file, fmt.Sprintf("./%s", file.Filename))
})
FormValue
获取指定字段的第一个值,字段不存在返回空字符串
FormValue(key string, defaultValue ...string) string
app.Post("/", func(c *fiber.Ctx) error {
c.FormValue("name")
})
Get
返回指定请求标头,大小写不敏感
Get(key string, defaultValue ...string) string
GetRespHeader
GetRespHeader(key string, defaultValue ...string) string
返回指定相应标头,大小写不敏感
JSON
将相应内容转换为 json 格式并将 Content-Type 设置为 application/json
JSON(data interface{}) error
app.Get("/json", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"name": "Grame",
"age": 20,
})
})
Links
设置相应的 Link 标头值
Links(link ...string)
app.Get("/", func(c *fiber.Ctx) error {
c.Links(
"http://api.example.com/users?page=2", "next",
"http://api.example.com/users?page=5", "last",
)
// Link: <http://api.example.com/users?page=2>; rel="next",
// <http://api.example.com/users?page=5>; rel="last"
})
Locals
用于存储限定于请求范围的变量,因此仅对与请求匹配的路由可用
要将某些数据传递给下一个中间件,则此选项非常有用
Locals(key string, value ...interface{}) interface{}
当不传入 value 时表示获取值,传入 value 时表示设定值
app.Use(func(c *fiber.Ctx) error {
c.Locals("user", "admin")
// 定义一个局部数据
return c.Next()
})
app.Get("/admin", func(c *fiber.Ctx) error {
if c.Locals("user") == "admin" {
// 获取传递的数据
return c.Status(fiber.StatusOK).SendString("Welcome")
}
return c.SendStatus(fiber.StatusForbidden)
})
Location
设置响应 Location 标头值
Location(path string)
app.Post("/", func(c *fiber.Ctx) error {
return c.Location("http://example.com")
return c.Location("/foo/bar")
})
Method
获取请求的方式字符串
Method(override ...string) string
MultipartForm
解析表单所有字段及上传文件内容(以二进制形式)
MultipartForm() (*multipart.Form, error)
app.Post("/", func(c *fiber.Ctx) error {
if form, err := c.MultipartForm(); err == nil {
if token := form.Value["token"]; len(token) > 0 {
//form.Value用于获取所有文本内容,map[string][]string
fmt.Println(token[0])
}
// //form.File用于获取所有上传文件
files := form.File["documents"]
// => []*multipart.FileHeader
//循环获取文件:
for _, file := range files {
fmt.Println(file.Filename, file.Size, file.Header["Content-Type"][0])
// => "demo.pdf" 56789 "application/pdf"
//将文件保存到磁盘:
if err := c.SaveFile(file, fmt.Sprintf("./%s", file.Filename)); err != nil {
return err
}
}
}
return err
})
Params
Params(key string, defaultValue ...string) string
可以传递一个可选的默认值,如果参数键不存在,将返回该值
GET http://example.com/user/fenny/123
路由:"/user/:name/:id"
c.Params("name") // "fenny"
c.Params("id") // "123"
对于未命名路由(使用星号),使用路由中的字符+数字来获取
路由:"/user/*/id/*"
c.Params("*1") // "fenny"
c.Params("*2") // "123"
参数不加数字默认返回第一个
c.Params("*") // "fenny"
Render
Render(name string, bind interface{}, layouts ...string) error
使用指定数据按指定的模板渲染并发送响应
name :模板名称
bind :绑定到模板的数据
layouts:模板布局,如果不提供将使用全局布局,如果没有指定全局布局按name查找
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/template/html/v2"
)
func main() {
// 初始化标准Go html模板引擎
engine := html.New("./views", ".html")
app := fiber.New(fiber.Config{
Views: engine,
})
app.Get("/", func(c *fiber.Ctx) error {
// 渲染 index 模板
return c.Render("index", fiber.Map{
"Title": "Hello, World!",
},"layouts/main")
})
app.Listen(":3000")
}
模板文件
<!DOCTYPE html>
<body>
<h1>{{.Title}}</h1>
</body>
</html>
SaveFile
SaveFile(fh *multipart.FileHeader, path string) error
将上传的文件保存到磁盘
app.Post("/", func(c *fiber.Ctx) error {
// 解析表单。
if form, err := c.MultipartForm(); err == nil {
// => *multipart.Form
// 从指定键中获取所有文件。
files := form.File["documents"]
// => []*multipart.FileHeader
for _, file := range files {
// 保存文件到磁盘。
if err := c.SaveFile(file, fmt.Sprintf("./%s", file.Filename)); err != nil {
return err
}
}
return err
}
})
Send
Send(body []byte) error
设置 HTTP 响应体
app.Get("/", func(c *fiber.Ctx) error {
return c.Send([]byte("Hello, World!"))
// "Hello, World!"
})
在此基础上还拓展了两个方法用于类型断言
SendString(body string) error
SendStream(stream io.Reader, size ...int) error
由于多出了一部分检测类型的操作,在性能上没有 Send 快
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World!")
return c.SendStream(bytes.NewReader([]byte("Hello, World!")))
})
SendFile
SendFile(file string, compress ...bool) error
从给定的路径传输文件,会自动根据文件扩展名设置 Content-Type
compress 表示是否启动 gzipping,默认 false
app.Get("/not-found", func(c *fiber.Ctx) error {
return c.SendFile("./public/404.html",true);
// 禁用压缩
return c.SendFile("./static/index.html", false);
})
如果文件包含url特定字符,必须将其进行转义
app.Get("/file-url-chars", func(c *fiber.Ctx) error {
return c.SendFile(url.PathEscape("hash_sign_#.txt"))
})
SendStatus
SendStatus(status int) error
当响应正文为空,设置状态码和状态消息
在调用之前调用 Send 函数表示要设置的状态消息,不设置采用默认的状态消息
app.Get("/not-found", func(c *fiber.Ctx) error {
return c.SendStatus(415)
// => 415 "Unsupported Media Type"
c.SendString("Hello, World!")
return c.SendStatus(415)
// => 415 "Hello, World!"
})
Status
Status(status int) *Ctx
设置响应的 HTTP 状态,返回一个上下文,可以实现链式调用
app.Get("/fiber", func(c *fiber.Ctx) error {
c.Status(fiber.StatusOK)
return nil
}
app.Get("/hello", func(c *fiber.Ctx) error {
return c.Status(fiber.StatusBadRequest).SendString("Bad Request")
}
app.Get("/world", func(c *fiber.Ctx) error {
return c.Status(fiber.StatusNotFound).SendFile("./public/gopher.png")
})
Subdomains
Subdomains(offset ...int) []string
返回请求的域名中的子域的字符串片断。
offset 表示子域偏移量,默认为 2
// 主机。"tobi.ferrets.example.com"
app.Get("/", func(c *fiber.Ctx) error {
c.Subdomains() // ["fielrets", "tobi"] 。
c.Subdomains(1) // ["tobi"] 。
})
Type
Type(ext string, charset ...string) *Ctx
将 Content-Type 头设置为指定的拓展名对应的 MIME
ext 表示拓展名,可以包含点也可以不包含点
获取拓展名可以使用"path/filepath"包中的filepath.Ext(file)来获取带点的后缀名字符串
app.Get("/", func(c *fiber.Ctx) error {
c.Type(".html") // => "text/html"
c.Type("png") // => "image/png"
c.Type("json", "utf-8") // => "application/json; charset=utf-8"
})
我们也可以使用Set(key,val)来设置响应头
import (
"mime"
"path/filepath"
)
c.Set("Content-Type", mime.TypeByExtension(filepath.Ext(file)))
Vary
Vary(field ...string)
将给定的值追加到 Vary 响应头中,允许一次传递多个值
app.Get("/", func(c *fiber.Ctx) error {
c.Vary("Origin") // => Vary: Origin
c.Vary("User-Agent") // => Vary: Origin, User-Agent
c.Vary("Accept-Encoding", "Accept")
// => Vary: Origin, User-Agent, Accept-Encoding, Accept
})
Write
Write(p []byte) (n int, err error)
采用 Writer 接口向相应主体中追加内容
app.Get("/", func(c *fiber.Ctx) error {
c.Write([]byte("Hello")
c.Write([]byte(" world")
})