🧠 Ctx
Accepts
检查指定的扩展名或内容类型是否可接受。
基于请求的 Accept HTTP 标头。
func (c *Ctx) Accepts(offers ...string) string
func (c *Ctx) AcceptsCharsets(offers ...string) string
func (c *Ctx) AcceptsEncodings(offers ...string) string
func (c *Ctx) AcceptsLanguages(offers ...string) string
// Accept: text/html, application/json; q=0.8, text/plain; q=0.5; charset="utf-8"
app.Get("/", func(c *fiber.Ctx) error {
c.Accepts("html") // "html"
c.Accepts("text/html") // "text/html"
c.Accepts("json", "text") // "json"
c.Accepts("application/json") // "application/json"
c.Accepts("text/plain", "application/json") // "application/json", due to quality
c.Accepts("image/png") // ""
c.Accepts("png") // ""
// ...
})
// Accept: text/html, text/*, application/json, */*; q=0
app.Get("/", func(c *fiber.Ctx) error {
c.Accepts("text/plain", "application/json") // "application/json", due to specificity
c.Accepts("application/json", "text/html") // "text/html", due to first match
c.Accepts("image/png") // "", due to */* without q factor 0 is Not Acceptable
// ...
})
支持媒体类型参数。
// Accept: text/plain, application/json; version=1; foo=bar
app.Get("/", func(c *fiber.Ctx) error {
// Extra parameters in the accept are ignored
c.Accepts("text/plain;format=flowed") // "text/plain;format=flowed"
// An offer must contain all parameters present in the Accept type
c.Accepts("application/json") // ""
// Parameter order and capitalization does not matter. Quotes on values are stripped.
c.Accepts(`application/json;foo="bar";VERSION=1`) // "application/json;foo="bar";VERSION=1"
})
// Accept: text/plain;format=flowed;q=0.9, text/plain
// i.e., "I prefer text/plain;format=flowed less than other forms of text/plain"
app.Get("/", func(c *fiber.Ctx) error {
// Beware: the order in which offers are listed matters.
// Although the client specified they prefer not to receive format=flowed,
// the text/plain Accept matches with "text/plain;format=flowed" first, so it is returned.
c.Accepts("text/plain;format=flowed", "text/plain") // "text/plain;format=flowed"
// Here, things behave as expected:
c.Accepts("text/plain", "text/plain;format=flowed") // "text/plain"
})
Fiber 为其他接受标头提供类似的功能。
// Accept-Charset: utf-8, iso-8859-1;q=0.2
// Accept-Encoding: gzip, compress;q=0.2
// Accept-Language: en;q=0.8, nl, ru
app.Get("/", func(c *fiber.Ctx) error {
c.AcceptsCharsets("utf-16", "iso-8859-1")
// "iso-8859-1"
c.AcceptsEncodings("compress", "br")
// "compress"
c.AcceptsLanguages("pt", "nl", "ru")
// "nl"
// ...
})
AllParams
Params 用于获取所有路由参数。使用 Params 方法获取参数。
func (c *Ctx) AllParams() map[string]string
// GET http://example.com/user/fenny
app.Get("/user/:name", func(c *fiber.Ctx) error {
c.AllParams() // "{"name": "fenny"}"
// ...
})
// GET http://example.com/user/fenny/123
app.Get("/user/*", func(c *fiber.Ctx) error {
c.AllParams() // "{"*1": "fenny/123"}"
// ...
})
App
返回 *App 引用,以便轻松访问所有应用程序设置。
func (c *Ctx) App() *App
app.Get("/stack", func(c *fiber.Ctx) error {
return c.JSON(c.App().Stack())
})
Append
将指定的值附加到 HTTP 响应标头字段。
如果标头尚未设置,它将使用指定的值创建标头。
func (c *Ctx) Append(field string, values ...string)
app.Get("/", func(c *fiber.Ctx) error {
c.Append("Link", "http://google.com", "https://127.0.0.1")
// => Link: https://127.0.0.1, http://google.com
c.Append("Link", "Test")
// => Link: https://127.0.0.1, http://google.com, Test
// ...
})
附件
将 HTTP 响应 Content-Disposition 标头字段设置为attachment
。
func (c *Ctx) Attachment(filename ...string)
app.Get("/", func(c *fiber.Ctx) error {
c.Attachment()
// => Content-Disposition: attachment
c.Attachment("./upload/images/logo.png")
// => Content-Disposition: attachment; filename="logo.png"
// => Content-Type: image/png
// ...
})
BaseURL
返回基本 URL(协议 + 主机)作为string
。
func (c *Ctx) BaseURL() string
// GET https://example.com/page#chapter-1
app.Get("/", func(c *fiber.Ctx) error {
c.BaseURL() // https://example.com
// ...
})
绑定
将变量添加到默认视图变量映射,绑定到模板引擎。变量由 Render 方法读取,并且可以被覆盖。
func (c *Ctx) Bind(vars Map) error
app.Use(func(c *fiber.Ctx) error {
c.Bind(fiber.Map{
"Title": "Hello, World!",
})
})
app.Get("/", func(c *fiber.Ctx) error {
return c.Render("xxx.tmpl", fiber.Map{}) // Render will use Title variable
})
BodyRaw
返回原始请求主体。
func (c *Ctx) BodyRaw() []byte
// curl -X POST https://127.0.0.1:8080 -d user=john
app.Post("/", func(c *fiber.Ctx) error {
// Get raw body from POST request:
return c.Send(c.BodyRaw()) // []byte("user=john")
})
主体
根据标头Content-Encoding
,此方法将尝试对主体字节执行文件解压缩。如果未发送Content-Encoding
标头,它将执行为 BodyRaw。
func (c *Ctx) Body() []byte
// echo 'user=john' | gzip | curl -v -i --data-binary @- -H "Content-Encoding: gzip" https://127.0.0.1:8080
app.Post("/", func(c *fiber.Ctx) error {
// Decompress body from POST request based on the Content-Encoding and return the raw content:
return c.Send(c.Body()) // []byte("user=john")
})
BodyParser
将请求主体绑定到结构。
根据要解析的内容类型指定正确的结构标记非常重要。例如,如果你想使用名为 Pass 的字段解析 JSON 主体,则可以使用json:"pass"
的结构字段。
内容类型 | 结构标记 |
---|---|
application/x-www-form-urlencoded | 表单 |
multipart/form-data | 表单 |
application/json | json |
application/xml | xml |
text/xml | xml |
func (c *Ctx) BodyParser(out interface{}) error
// Field names should start with an uppercase letter
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
// ...
})
// Run tests with the following curl commands
// 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 https://127.0.0.1:3000
// curl -X POST "https://127.0.0.1:3000/?name=john&pass=doe"
ClearCookie
使客户端 cookie 过期(如果留空,则使所有 cookie 过期)
func (c *Ctx) ClearCookie(key ...string)
app.Get("/", func(c *fiber.Ctx) error {
// Clears all cookies:
c.ClearCookie()
// Expire specific cookie by name:
c.ClearCookie("user")
// Expire multiple cookies by names:
c.ClearCookie("token", "session", "track_id", "version")
// ...
})
仅当给定的选项与创建 cookie 时的选项(不包括 expires 和 maxAge)相同,Web 浏览器和其他兼容客户端才会清除 cookie。ClearCookie 不会为您设置这些值 - 应使用类似于下面所示的技术来确保删除您的 cookie。
app.Get("/set", func(c *fiber.Ctx) error {
c.Cookie(&fiber.Cookie{
Name: "token",
Value: "randomvalue",
Expires: time.Now().Add(24 * time.Hour),
HTTPOnly: true,
SameSite: "lax",
})
// ...
})
app.Get("/delete", func(c *fiber.Ctx) error {
c.Cookie(&fiber.Cookie{
Name: "token",
// Set expiry date to the past
Expires: time.Now().Add(-(time.Hour * 2)),
HTTPOnly: true,
SameSite: "lax",
})
// ...
})
ClientHelloInfo
ClientHelloInfo 包含 ClientHello 消息中的信息,以便在 GetCertificate 和 GetConfigForClient 回调中指导应用程序逻辑。您可以参考 ClientHelloInfo 结构文档,以获取有关返回的结构的更多信息。
func (c *Ctx) ClientHelloInfo() *tls.ClientHelloInfo
// GET http://example.com/hello
app.Get("/hello", func(c *fiber.Ctx) error {
chi := c.ClientHelloInfo()
// ...
})
Context
返回 *fasthttp.RequestCtx,它与 context.Context 接口兼容,该接口需要一个截止时间、一个取消信号以及 API 边界上的其他值。
func (c *Ctx) Context() *fasthttp.RequestCtx
请阅读 Fasthttp 文档 以获取更多信息。
Cookie
设置 cookie
func (c *Ctx) 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"`
SessionOnly bool `json:"session_only"`
}
app.Get("/", func(c *fiber.Ctx) error {
// Create cookie
cookie := new(fiber.Cookie)
cookie.Name = "john"
cookie.Value = "doe"
cookie.Expires = time.Now().Add(24 * time.Hour)
// Set cookie
c.Cookie(cookie)
// ...
})
CookieParser
此方法类似于 BodyParser,但适用于 cookie 参数。使用结构标签“cookie”非常重要。例如,如果您想解析一个带有名为 Age 的字段的 cookie,则可以使用 cookie:"age"
的结构字段。
func (c *Ctx) CookieParser(out interface{}) error
// Field names should start with an uppercase letter
type Person struct {
Name string `cookie:"name"`
Age int `cookie:"age"`
Job bool `cookie:"job"`
}
app.Get("/", func(c *fiber.Ctx) error {
p := new(Person)
if err := c.CookieParser(p); err != nil {
return err
}
log.Println(p.Name) // Joseph
log.Println(p.Age) // 23
log.Println(p.Job) // true
})
// Run tests with the following curl command
// curl.exe --cookie "name=Joseph; age=23; job=true" https://127.0.0.1:8000/
Cookies
按键获取 cookie 值,您可以传递一个可选的默认值,如果 cookie 键不存在,则将返回该默认值。
func (c *Ctx) Cookies(key string, defaultValue ...string) string
app.Get("/", func(c *fiber.Ctx) error {
// Get cookie by key:
c.Cookies("name") // "john"
c.Cookies("empty", "doe") // "doe"
// ...
})
Download
将文件从路径作为 attachment
传输。
通常,浏览器会提示用户下载。默认情况下,Content-Disposition 标头 filename=
参数是文件路径(这通常出现在浏览器对话框中)。
使用 filename 参数覆盖此默认设置。
func (c *Ctx) Download(file string, filename ...string) error
app.Get("/", func(c *fiber.Ctx) error {
return c.Download("./files/report-12345.pdf");
// => Download report-12345.pdf
return c.Download("./files/report-12345.pdf", "report.pdf");
// => Download report.pdf
})
Format
对 Accept HTTP 标头执行内容协商。它使用 Accepts 选择适当的格式。
如果未指定标头或没有适当的格式,则使用text/plain。
func (c *Ctx) Format(body interface{}) error
app.Get("/", func(c *fiber.Ctx) error {
// Accept: text/plain
c.Format("Hello, World!")
// => Hello, World!
// Accept: text/html
c.Format("Hello, World!")
// => <p>Hello, World!</p>
// Accept: application/json
c.Format("Hello, World!")
// => "Hello, World!"
// ..
})
FormFile
可以通过名称检索 MultipartForm 文件,将返回给定键的第一个文件。
func (c *Ctx) FormFile(key string) (*multipart.FileHeader, error)
app.Post("/", func(c *fiber.Ctx) error {
// Get first file from form field "document":
file, err := c.FormFile("document")
// Save file to root directory:
return c.SaveFile(file, fmt.Sprintf("./%s", file.Filename))
})
FormValue
可以通过名称检索任何表单值,将返回给定键的第一个值。
func (c *Ctx) FormValue(key string, defaultValue ...string) string
app.Post("/", func(c *fiber.Ctx) error {
// Get first value from form field "name":
c.FormValue("name")
// => "john" or "" if not exist
// ..
})
Fresh
当响应在客户端缓存中仍然新鲜时,返回true;否则,返回false以指示客户端缓存现在已过时,应发送完整响应。
当客户端发送 Cache-Control: no-cache 请求标头以指示端到端重新加载请求时,Fresh
将返回 false 以使处理这些请求变得透明。
阅读更多内容:https://express.js.cn/en/4x/api.html#req.fresh
func (c *Ctx) Fresh() bool
Get
返回字段指定的 HTTP 请求标头。
匹配不区分大小写。
func (c *Ctx) Get(key string, defaultValue ...string) string
app.Get("/", func(c *fiber.Ctx) error {
c.Get("Content-Type") // "text/plain"
c.Get("CoNtEnT-TypE") // "text/plain"
c.Get("something", "john") // "john"
// ..
})
GetReqHeaders
以映射的形式返回 HTTP 请求标头。由于在单个请求中可以多次设置标头,因此映射的值是字符串切片,其中包含标头的所有不同值。
func (c *Ctx) GetReqHeaders() map[string][]string
GetRespHeader
返回字段指定的 HTTP 响应标头。
匹配不区分大小写。
func (c *Ctx) GetRespHeader(key string, defaultValue ...string) string
app.Get("/", func(c *fiber.Ctx) error {
c.GetRespHeader("X-Request-Id") // "8d7ad5e3-aaf3-450b-a241-2beb887efd54"
c.GetRespHeader("Content-Type") // "text/plain"
c.GetRespHeader("something", "john") // "john"
// ..
})
GetRespHeaders
以映射的形式返回 HTTP 响应标头。由于在单个请求中可以多次设置标头,因此映射的值是字符串切片,其中包含标头的所有不同值。
func (c *Ctx) GetRespHeaders() map[string][]string
GetRouteURL
生成带有参数的已命名路由的 URL。URL 是相对的,例如:"/user/1831"
func (c *Ctx) GetRouteURL(routeName string, params Map) (string, error)
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Home page")
}).Name("home")
app.Get("/user/:id", func(c *fiber.Ctx) error {
return c.SendString(c.Params("id"))
}).Name("user.show")
app.Get("/test", func(c *fiber.Ctx) error {
location, _ := c.GetRouteURL("user.show", fiber.Map{"id": 1})
return c.SendString(location)
})
// /test returns "/user/1"
Hostname
从Host HTTP 标头派生并返回主机名。
func (c *Ctx) Hostname() string
// GET http://google.com/search
app.Get("/", func(c *fiber.Ctx) error {
c.Hostname() // "google.com"
// ...
})
IP
返回请求的远程 IP 地址。
func (c *Ctx) IP() string
app.Get("/", func(c *fiber.Ctx) error {
c.IP() // "127.0.0.1"
// ...
})
在 fiber 应用中注册代理请求头时,返回头部的 IP 地址 (Fiber 配置)
app := fiber.New(fiber.Config{
ProxyHeader: fiber.HeaderXForwardedFor,
})
IP
返回 X-Forwarded-For 请求头中指定的 IP 地址数组。
func (c *Ctx) IPs() []string
// X-Forwarded-For: proxy1, 127.0.0.1, proxy3
app.Get("/", func(c *fiber.Ctx) error {
c.IPs() // ["proxy1", "127.0.0.1", "proxy3"]
// ...
})
不当使用 X-Forwarded-For 头部可能存在安全风险。有关详细信息,请参阅 安全性和隐私问题 部分。
Is
如果传入请求的 Content-Type HTTP 头部字段与 type 参数指定的 MIME 类型 匹配,则返回匹配的内容类型。
如果请求没有主体,则返回false。
func (c *Ctx) Is(extension string) bool
// Content-Type: text/html; charset=utf-8
app.Get("/", func(c *fiber.Ctx) error {
c.Is("html") // true
c.Is(".html") // true
c.Is("json") // false
// ...
})
IsFromLocal
如果请求来自 localhost,则返回 true
func (c *Ctx) IsFromLocal() bool {
app.Get("/", func(c *fiber.Ctx) error {
// If request came from localhost, return true else return false
c.IsFromLocal()
// ...
})
JSON
使用 encoding/json 包将任何接口或字符串转换为 JSON。
JSON 还会将内容头部设置为 ctype
参数。如果没有传入 ctype
,则头部将设置为 application/json
。
func (c *Ctx) JSON(data interface{}, ctype ...string) error
type SomeStruct struct {
Name string
Age uint8
}
app.Get("/json", func(c *fiber.Ctx) error {
// Create data struct:
data := SomeStruct{
Name: "Grame",
Age: 20,
}
return c.JSON(data)
// => Content-Type: application/json
// => "{"Name": "Grame", "Age": 20}"
return c.JSON(fiber.Map{
"name": "Grame",
"age": 20,
})
// => Content-Type: application/json
// => "{"name": "Grame", "age": 20}"
return c.JSON(fiber.Map{
"type": "https://example.com/probs/out-of-credit",
"title": "You do not have enough credit.",
"status": 403,
"detail": "Your current balance is 30, but that costs 50.",
"instance": "/account/12345/msgs/abc",
}, "application/problem+json")
// => Content-Type: application/problem+json
// => "{
// => "type": "https://example.com/probs/out-of-credit",
// => "title": "You do not have enough credit.",
// => "status": 403,
// => "detail": "Your current balance is 30, but that costs 50.",
// => "instance": "/account/12345/msgs/abc",
// => }"
})
JSONP
发送带有 JSONP 支持的 JSON 响应。此方法与 JSON 相同,只是它选择加入 JSONP 回调支持。默认情况下,回调名称只是回调。
通过在方法中传递命名字符串来覆盖此项。
func (c *Ctx) JSONP(data interface{}, callback ...string) error
type SomeStruct struct {
name string
age uint8
}
app.Get("/", func(c *fiber.Ctx) error {
// Create data struct:
data := SomeStruct{
name: "Grame",
age: 20,
}
return c.JSONP(data)
// => callback({"name": "Grame", "age": 20})
return c.JSONP(data, "customFunc")
// => customFunc({"name": "Grame", "age": 20})
})
Links
连接属性后面跟随的链接以填充响应的 Link HTTP 头部字段。
func (c *Ctx) 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
一种存储限定于请求范围内的变量的方法,因此仅对与请求匹配的路由可用。
如果你想将一些特定数据传递到下一个中间件,这将非常有用。
func (c *Ctx) Locals(key interface{}, value ...interface{}) interface{}
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, admin!")
}
return c.SendStatus(fiber.StatusForbidden)
})
Location
将响应 Location HTTP 标头设置为指定的路径参数。
func (c *Ctx) Location(path string)
app.Post("/", func(c *fiber.Ctx) error {
c.Location("http://example.com")
c.Location("/foo/bar")
return nil
})
方法
返回与请求的 HTTP 方法相对应的字符串:GET
、POST
、PUT
等。
或者,你可以通过传递一个字符串来覆盖方法。
func (c *Ctx) Method(override ...string) string
app.Post("/", func(c *fiber.Ctx) error {
c.Method() // "POST"
c.Method("GET")
c.Method() // GET
// ...
})
MultipartForm
要访问 multipart 表单条目,可以使用 MultipartForm()
解析二进制文件。这会返回一个 map[string][]string
,因此给定一个键,值将是一个字符串切片。
func (c *Ctx) MultipartForm() (*multipart.Form, error)
app.Post("/", func(c *fiber.Ctx) error {
// Parse the multipart form:
if form, err := c.MultipartForm(); err == nil {
// => *multipart.Form
if token := form.Value["token"]; len(token) > 0 {
// Get key value:
fmt.Println(token[0])
}
// Get all files from "documents" key:
files := form.File["documents"]
// => []*multipart.FileHeader
// Loop through files:
for _, file := range files {
fmt.Println(file.Filename, file.Size, file.Header["Content-Type"][0])
// => "tutorial.pdf" 360641 "application/pdf"
// Save the files to disk:
if err := c.SaveFile(file, fmt.Sprintf("./%s", file.Filename)); err != nil {
return err
}
}
}
return err
})
Next
调用 Next 时,它将执行与当前路由匹配的堆栈中的下一个方法。你可以在方法中传递一个错误结构,该结构将结束链接并调用 错误处理程序。
func (c *Ctx) Next() error
app.Get("/", func(c *fiber.Ctx) error {
fmt.Println("1st route!")
return c.Next()
})
app.Get("*", func(c *fiber.Ctx) error {
fmt.Println("2nd route!")
return c.Next()
})
app.Get("/", func(c *fiber.Ctx) error {
fmt.Println("3rd route!")
return c.SendString("Hello, World!")
})
OriginalURL
返回原始请求 URL。
func (c *Ctx) OriginalURL() string
// GET http://example.com/search?q=something
app.Get("/", func(c *fiber.Ctx) error {
c.OriginalURL() // "/search?q=something"
// ...
})
Params
方法可用于获取路由参数,你可以传递一个可选的默认值,如果参数键不存在,则将返回该默认值。
如果参数不存在,则默认为空字符串 (""
)。
func (c *Ctx) Params(key string, defaultValue ...string) string
// GET http://example.com/user/fenny
app.Get("/user/:name", func(c *fiber.Ctx) error {
c.Params("name") // "fenny"
// ...
})
// GET http://example.com/user/fenny/123
app.Get("/user/*", func(c *fiber.Ctx) error {
c.Params("*") // "fenny/123"
c.Params("*1") // "fenny/123"
// ...
})
可以通过路由中的字符和计数器获取未命名的路由参数(*, +)。
// ROUTE: /v1/*/shop/*
// GET: /v1/brand/4/shop/blue/xs
c.Params("*1") // "brand/4"
c.Params("*2") // "blue/xs"
出于向下兼容性的原因,参数字符的第一个参数段也可以在没有计数器的情况下访问。
app.Get("/v1/*/shop/*", func(c *fiber.Ctx) error {
c.Params("*") // outputs the values of the first wildcard segment
})
ParamsInt
方法可用于从路由参数中获取整数。请注意,如果请求中没有该参数,则会返回零。如果参数不是数字,则会返回零和错误
如果参数不存在,则默认为整数零 (0
)。
func (c *Ctx) ParamsInt(key string) (int, error)
// GET http://example.com/user/123
app.Get("/user/:id", func(c *fiber.Ctx) error {
id, err := c.ParamsInt("id") // int 123 and no error
// ...
})
此方法等效于将 atoi
与 ctx.Params 一起使用
ParamsParser
此方法类似于 BodyParser,但适用于路径参数。重要的是使用结构标记“params”。例如,如果你想使用名为 Pass 的字段解析路径参数,则可以使用 params:"pass" 的结构字段
func (c *Ctx) ParamsParser(out interface{}) error
// GET http://example.com/user/111
app.Get("/user/:id", func(c *fiber.Ctx) error {
param := struct {ID uint `params:"id"`}{}
c.ParamsParser(¶m) // "{"id": 111}"
// ...
})
Path
包含请求 URL 的路径部分。或者,你可以通过传递字符串来覆盖路径。对于内部重定向,你可能希望调用 RestartRouting 而不是 Next。
func (c *Ctx) Path(override ...string) string
// GET http://example.com/users?sort=desc
app.Get("/users", func(c *fiber.Ctx) error {
c.Path() // "/users"
c.Path("/john")
c.Path() // "/john"
// ...
})
协议
包含请求协议字符串:http
或 https
,用于 TLS 请求。
func (c *Ctx) Protocol() string
// GET http://example.com
app.Get("/", func(c *fiber.Ctx) error {
c.Protocol() // "http"
// ...
})
查询
Queries 是一个函数,它返回一个对象,其中包含一个属性,用于路由中的每个查询字符串参数。
func (c *Ctx) Queries() map[string]string
// GET http://example.com/?name=alex&want_pizza=false&id=
app.Get("/", func(c *fiber.Ctx) error {
m := c.Queries()
m["name"] // "alex"
m["want_pizza"] // "false"
m["id"] // ""
// ...
})
// GET http://example.com/?field1=value1&field1=value2&field2=value3
app.Get("/", func (c *fiber.Ctx) error {
m := c.Queries()
m["field1"] // "value2"
m["field2"] // value3
})
// GET http://example.com/?list_a=1&list_a=2&list_a=3&list_b[]=1&list_b[]=2&list_b[]=3&list_c=1,2,3
app.Get("/", func(c *fiber.Ctx) error {
m := c.Queries()
m["list_a"] // "3"
m["list_b[]"] // "3"
m["list_c"] // "1,2,3"
})
// GET /api/posts?filters.author.name=John&filters.category.name=Technology
app.Get("/", func(c *fiber.Ctx) error {
m := c.Queries()
m["filters.author.name"] // John
m["filters.category.name"] // Technology
})
// GET /api/posts?tags=apple,orange,banana&filters[tags]=apple,orange,banana&filters[category][name]=fruits&filters.tags=apple,orange,banana&filters.category.name=fruits
app.Get("/", func(c *fiber.Ctx) error {
m := c.Queries()
m["tags"] // apple,orange,banana
m["filters[tags]"] // apple,orange,banana
m["filters[category][name]"] // fruits
m["filters.tags"] // apple,orange,banana
m["filters.category.name"] // fruits
})
查询
此属性是一个对象,其中包含一个属性,用于路由中的每个查询字符串参数,你可以传递一个可选的默认值,如果查询键不存在,则将返回该默认值。
如果没有查询字符串,它将返回一个空字符串。
func (c *Ctx) Query(key string, defaultValue ...string) string
// GET http://example.com/?order=desc&brand=nike
app.Get("/", func(c *fiber.Ctx) error {
c.Query("order") // "desc"
c.Query("brand") // "nike"
c.Query("empty", "nike") // "nike"
// ...
})
QueryBool
此属性是一个对象,其中包含一个属性,用于路由中的每个查询布尔参数,你可以传递一个可选的默认值,如果查询键不存在,则将返回该默认值。
请注意,如果请求中没有该参数,则将返回 false。如果该参数不是布尔值,它仍会尝试进行转换,并且通常返回 false。
func (c *Ctx) QueryBool(key string, defaultValue ...bool) bool
// GET http://example.com/?name=alex&want_pizza=false&id=
app.Get("/", func(c *fiber.Ctx) error {
c.QueryBool("want_pizza") // false
c.QueryBool("want_pizza", true) // false
c.QueryBool("name") // false
c.QueryBool("name", true) // true
c.QueryBool("id") // false
c.QueryBool("id", true) // true
// ...
})
QueryFloat
此属性是一个对象,其中包含一个属性,用于路由中的每个查询 float64 参数,你可以传递一个可选的默认值,如果查询键不存在,则将返回该默认值。
请注意,如果请求中没有该参数,则将返回零。如果该参数不是数字,它仍会尝试进行转换,并且通常返回 1。
如果参数不存在,则默认为 float64 零 (0
)。
func (c *Ctx) QueryFloat(key string, defaultValue ...float64) float64
// GET http://example.com/?name=alex&amount=32.23&id=
app.Get("/", func(c *fiber.Ctx) error {
c.QueryFloat("amount") // 32.23
c.QueryFloat("amount", 3) // 32.23
c.QueryFloat("name", 1) // 1
c.QueryFloat("name") // 0
c.QueryFloat("id", 3) // 3
// ...
})
QueryInt
此属性是一个对象,其中包含一个属性,用于路由中的每个查询整数参数,你可以传递一个可选的默认值,如果查询键不存在,则将返回该默认值。
请注意,如果请求中没有该参数,则将返回零。如果该参数不是数字,它仍会尝试进行转换,并且通常返回 1。
如果参数不存在,则默认为整数零 (0
)。
func (c *Ctx) QueryInt(key string, defaultValue ...int) int
// GET http://example.com/?name=alex&wanna_cake=2&id=
app.Get("/", func(c *fiber.Ctx) error {
c.QueryInt("wanna_cake", 1) // 2
c.QueryInt("name", 1) // 1
c.QueryInt("id", 1) // 1
c.QueryInt("id") // 0
// ...
})
QueryParser
此方法类似于 BodyParser,但用于查询参数。使用结构体标记“query”非常重要。例如,如果你想使用名为 Pass 的字段解析查询参数,则可以使用结构体字段 query:"pass"
。
func (c *Ctx) QueryParser(out interface{}) error
// Field names should start with an uppercase letter
type Person struct {
Name string `query:"name"`
Pass string `query:"pass"`
Products []string `query:"products"`
}
app.Get("/", func(c *fiber.Ctx) error {
p := new(Person)
if err := c.QueryParser(p); err != nil {
return err
}
log.Println(p.Name) // john
log.Println(p.Pass) // doe
// fiber.Config{EnableSplittingOnParsers: false} - default
log.Println(p.Products) // ["shoe,hat"]
// fiber.Config{EnableSplittingOnParsers: true}
// log.Println(p.Products) // ["shoe", "hat"]
// ...
})
// Run tests with the following curl command
// curl "https://127.0.0.1:3000/?name=john&pass=doe&products=shoe,hat"
有关更多解析器设置,请查看此处 配置
Range
将返回包含类型和范围切片的结构。
func (c *Ctx) Range(size int) (Range, error)
// Range: bytes=500-700, 700-900
app.Get("/", func(c *fiber.Ctx) error {
b := c.Range(1000)
if b.Type == "bytes" {
for r := range r.Ranges {
fmt.Println(r)
// [500, 700]
}
}
})
Redirect
重定向到从指定路径派生的 URL,并带有指定状态,一个对应于 HTTP 状态代码的正整数。
如果未指定,状态默认为302 已找到。
func (c *Ctx) Redirect(location string, status ...int) error
app.Get("/coffee", func(c *fiber.Ctx) error {
return c.Redirect("/teapot")
})
app.Get("/teapot", func(c *fiber.Ctx) error {
return c.Status(fiber.StatusTeapot).Send("🍵 short and stout 🍵")
})
app.Get("/", func(c *fiber.Ctx) error {
return c.Redirect("/foo/bar")
return c.Redirect("../login")
return c.Redirect("http://example.com")
return c.Redirect("http://example.com", 301)
})
RedirectToRoute
重定向到特定路由以及参数,并带有指定状态,一个对应于 HTTP 状态代码的正整数。
如果未指定,状态默认为302 已找到。
如果你想向路由发送查询,你必须向 params 添加键入为map[string]string 的“queries” 键。
func (c *Ctx) RedirectToRoute(routeName string, params fiber.Map, status ...int) error
app.Get("/", func(c *fiber.Ctx) error {
// /user/fiber
return c.RedirectToRoute("user", fiber.Map{
"name": "fiber"
})
})
app.Get("/with-queries", func(c *fiber.Ctx) error {
// /user/fiber?data[0][name]=john&data[0][age]=10&test=doe
return c.RedirectToRoute("user", fiber.Map{
"name": "fiber",
"queries": map[string]string{"data[0][name]": "john", "data[0][age]": "10", "test": "doe"},
})
})
app.Get("/user/:name", func(c *fiber.Ctx) error {
return c.SendString(c.Params("name"))
}).Name("user")
RedirectBack
重定向回引用 URL。如果引用头不存在,它将重定向到后备 URL,并带有指定状态,一个对应于 HTTP 状态代码的正整数。
如果未指定,状态默认为302 已找到。
func (c *Ctx) RedirectBack(fallback string, status ...int) error
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Home page")
})
app.Get("/test", func(c *fiber.Ctx) error {
c.Set("Content-Type", "text/html")
return c.SendString(`<a href="/back">Back</a>`)
})
app.Get("/back", func(c *fiber.Ctx) error {
return c.RedirectBack("/")
})
Render
使用数据呈现视图并发送text/html
响应。默认情况下,Render
使用默认的Go 模板引擎。如果你想使用其他视图引擎,请查看我们的模板中间件。
func (c *Ctx) Render(name string, bind interface{}, layouts ...string) error
Request
Request 返回*fasthttp.Request 指针
func (c *Ctx) Request() *fasthttp.Request
app.Get("/", func(c *fiber.Ctx) error {
c.Request().Header.Method()
// => []byte("GET")
})
ReqHeaderParser
此方法类似于BodyParser,但适用于请求头。重要的是使用结构标签“reqHeader”。例如,如果你想使用名为 Pass 的字段解析请求头,你将使用reqHeader:"pass"
的结构字段。
func (c *Ctx) ReqHeaderParser(out interface{}) error
// Field names should start with an uppercase letter
type Person struct {
Name string `reqHeader:"name"`
Pass string `reqHeader:"pass"`
Products []string `reqHeader:"products"`
}
app.Get("/", func(c *fiber.Ctx) error {
p := new(Person)
if err := c.ReqHeaderParser(p); err != nil {
return err
}
log.Println(p.Name) // john
log.Println(p.Pass) // doe
log.Println(p.Products) // [shoe, hat]
// ...
})
// Run tests with the following curl command
// curl "https://127.0.0.1:3000/" -H "name: john" -H "pass: doe" -H "products: shoe,hat"
Response
Response 返回*fasthttp.Response 指针
func (c *Ctx) Response() *fasthttp.Response
app.Get("/", func(c *fiber.Ctx) error {
c.Response().BodyWriter().Write([]byte("Hello, World!"))
// => "Hello, World!"
return nil
})
RestartRouting
调用 Next 时,不会执行下一个方法,RestartRouting 会从与当前路由匹配的第一个方法重新开始执行。这在覆盖路径(即内部重定向)后可能很有用。请注意,处理程序可能会再次执行,这可能会导致无限循环。
func (c *Ctx) RestartRouting() error
app.Get("/new", func(c *fiber.Ctx) error {
return c.SendString("From /new")
})
app.Get("/old", func(c *fiber.Ctx) error {
c.Path("/new")
return c.RestartRouting()
})
Route
返回匹配的 Route 结构。
func (c *Ctx) Route() *Route
// https://127.0.0.1:8080/hello
app.Get("/hello/:name", func(c *fiber.Ctx) error {
r := c.Route()
fmt.Println(r.Method, r.Path, r.Params, r.Handlers)
// GET /hello/:name handler [name]
// ...
})
在调用 c.Next()
之前,不要依赖中间件中的 c.Route()
- c.Route()
返回最后执行的路由。
func MyMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
beforeNext := c.Route().Path // Will be '/'
err := c.Next()
afterNext := c.Route().Path // Will be '/hello/:name'
return err
}
}
SaveFile
该方法用于将任何多部分文件保存到磁盘。
func (c *Ctx) SaveFile(fh *multipart.FileHeader, path string) error
app.Post("/", func(c *fiber.Ctx) error {
// Parse the multipart form:
if form, err := c.MultipartForm(); err == nil {
// => *multipart.Form
// Get all files from "documents" key:
files := form.File["documents"]
// => []*multipart.FileHeader
// Loop through files:
for _, file := range files {
fmt.Println(file.Filename, file.Size, file.Header["Content-Type"][0])
// => "tutorial.pdf" 360641 "application/pdf"
// Save the files to disk:
if err := c.SaveFile(file, fmt.Sprintf("./%s", file.Filename)); err != nil {
return err
}
}
return err
}
})
SaveFileToStorage
该方法用于将任何多部分文件保存到外部存储系统。
func (c *Ctx) SaveFileToStorage(fileheader *multipart.FileHeader, path string, storage Storage) error
storage := memory.New()
app.Post("/", func(c *fiber.Ctx) error {
// Parse the multipart form:
if form, err := c.MultipartForm(); err == nil {
// => *multipart.Form
// Get all files from "documents" key:
files := form.File["documents"]
// => []*multipart.FileHeader
// Loop through files:
for _, file := range files {
fmt.Println(file.Filename, file.Size, file.Header["Content-Type"][0])
// => "tutorial.pdf" 360641 "application/pdf"
// Save the files to storage:
if err := c.SaveFileToStorage(file, fmt.Sprintf("./%s", file.Filename), storage); err != nil {
return err
}
}
return err
}
})
Secure
如果建立了TLS连接,则为 true
的布尔属性。
func (c *Ctx) Secure() bool
// Secure() method is equivalent to:
c.Protocol() == "https"
Send
设置 HTTP 响应主体。
func (c *Ctx) Send(body []byte) error
app.Get("/", func(c *fiber.Ctx) error {
return c.Send([]byte("Hello, World!")) // => "Hello, World!"
})
Fiber 还为原始输入提供了 SendString
和 SendStream
方法。
如果你不需要类型断言,请使用此方法,建议用于更快的性能。
func (c *Ctx) SendString(body string) error
func (c *Ctx) SendStream(stream io.Reader, size ...int) error
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World!")
// => "Hello, World!"
return c.SendStream(bytes.NewReader([]byte("Hello, World!")))
// => "Hello, World!"
})
SendFile
从给定路径传输文件。根据文件名扩展名设置 Content-Type 响应 HTTP 头字段。
该方法默认不使用gzip 压缩,将其设置为 true 以启用。
func (c *Ctx) SendFile(file string, compress ...bool) error
app.Get("/not-found", func(c *fiber.Ctx) error {
return c.SendFile("./public/404.html");
// Disable compression
return c.SendFile("./static/index.html", false);
})
如果该文件包含特定于 URL 的字符,则必须在将文件路径传递到 sendFile
函数之前对其进行转义。
app.Get("/file-with-url-chars", func(c *fiber.Ctx) error {
return c.SendFile(url.PathEscape("hash_sign_#.txt"))
})
要从嵌入式文件系统发送文件,可以使用此功能
SendStatus
如果响应主体为空,则设置状态代码和主体中的正确状态消息。
你可以在此处找到所有已使用的状态代码和消息。
func (c *Ctx) SendStatus(status int) error
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!"
})
Set
将响应的 HTTP 头字段设置为指定的 key
、value
。
func (c *Ctx) Set(key string, val string)
app.Get("/", func(c *fiber.Ctx) error {
c.Set("Content-Type", "text/plain")
// => "Content-type: text/plain"
// ...
})
SetParserDecoder
允许你根据架构选项配置 BodyParser/QueryParser 解码器,提供添加自定义类型以进行解析的可能性。
func SetParserDecoder(parserConfig fiber.ParserConfig{
IgnoreUnknownKeys bool,
ParserType []fiber.ParserType{
Customtype interface{},
Converter func(string) reflect.Value,
},
ZeroEmpty bool,
SetAliasTag string,
})
type CustomTime time.Time
// String() returns the time in string
func (ct *CustomTime) String() string {
t := time.Time(*ct).String()
return t
}
// Register the converter for CustomTime type format as 2006-01-02
var timeConverter = func(value string) reflect.Value {
fmt.Println("timeConverter", value)
if v, err := time.Parse("2006-01-02", value); err == nil {
return reflect.ValueOf(v)
}
return reflect.Value{}
}
customTime := fiber.ParserType{
Customtype: CustomTime{},
Converter: timeConverter,
}
// Add setting to the Decoder
fiber.SetParserDecoder(fiber.ParserConfig{
IgnoreUnknownKeys: true,
ParserType: []fiber.ParserType{customTime},
ZeroEmpty: true,
})
// Example to use CustomType, you pause custom time format not in RFC3339
type Demo struct {
Date CustomTime `form:"date" query:"date"`
Title string `form:"title" query:"title"`
Body string `form:"body" query:"body"`
}
app.Post("/body", func(c *fiber.Ctx) error {
var d Demo
c.BodyParser(&d)
fmt.Println("d.Date", d.Date.String())
return c.JSON(d)
})
app.Get("/query", func(c *fiber.Ctx) error {
var d Demo
c.QueryParser(&d)
fmt.Println("d.Date", d.Date.String())
return c.JSON(d)
})
// curl -X POST -F title=title -F body=body -F date=2021-10-20 https://127.0.0.1:3000/body
// curl -X GET "https://127.0.0.1:3000/query?title=title&body=body&date=2021-10-20"
SetUserContext
设置上下文接口的用户指定实现。
func (c *Ctx) SetUserContext(ctx context.Context)
app.Get("/", func(c *fiber.Ctx) error {
ctx := context.Background()
c.SetUserContext(ctx)
// Here ctx could be any context implementation
// ...
})
Stale
https://express.js.cn/en/4x/api.html#req.stale
func (c *Ctx) Stale() bool
Status
设置响应的 HTTP 状态。
Method 是一个可链式的。
func (c *Ctx) Status(status int) *Ctx
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
返回请求域名中子域名的字符串切片。
应用程序属性子域名偏移量(默认为2
)用于确定子域名段的开头。
func (c *Ctx) Subdomains(offset ...int) []string
// Host: "tobi.ferrets.example.com"
app.Get("/", func(c *fiber.Ctx) error {
c.Subdomains() // ["ferrets", "tobi"]
c.Subdomains(1) // ["tobi"]
// ...
})
Type
将Content-Type HTTP 标头设置为由文件扩展名指定的 MIME 类型,该类型在此处列出 。
func (c *Ctx) Type(ext string, charset ...string) *Ctx
app.Get("/", func(c *fiber.Ctx) error {
c.Type(".html") // => "text/html"
c.Type("html") // => "text/html"
c.Type("png") // => "image/png"
c.Type("json", "utf-8") // => "application/json; charset=utf-8"
// ...
})
UserContext
UserContext 返回用户之前设置的上下文实现,或者如果之前未设置,则返回一个非空、空上下文。
func (c *Ctx) UserContext() context.Context
app.Get("/", func(c *fiber.Ctx) error {
ctx := c.UserContext()
// ctx is context implementation set by user
// ...
})
Vary
将给定的标头字段添加到Vary响应标头。如果尚未列出,这将附加标头,否则将其保留在当前位置列出。
允许多个字段。
func (c *Ctx) Vary(fields ...string)
app.Get("/", func(c *fiber.Ctx) error {
c.Vary("Origin") // => Vary: Origin
c.Vary("User-Agent") // => Vary: Origin, User-Agent
// No duplicates
c.Vary("Origin") // => Vary: Origin, User-Agent
c.Vary("Accept-Encoding", "Accept")
// => Vary: Origin, User-Agent, Accept-Encoding, Accept
// ...
})
Write
Write 采用 Writer 接口
func (c *Ctx) Write(p []byte) (n int, err error)
app.Get("/", func(c *fiber.Ctx) error {
c.Write([]byte("Hello, World!")) // => "Hello, World!"
fmt.Fprintf(c, "%s\n", "Hello, World!") // "Hello, World!Hello, World!"
})
Writef
Writef 采用带有变量的字符串
func (c *Ctx) Writef(f string, a ...interface{}) (n int, err error)
app.Get("/", func(c *fiber.Ctx) error {
world := "World!"
c.Writef("Hello, %s", world) // => "Hello, World!"
fmt.Fprintf(c, "%s\n", "Hello, World!") // "Hello, World!Hello, World!"
})
WriteString
WriteString 采用字符串
func (c *Ctx) WriteString(s string) (n int, err error)
app.Get("/", func(c *fiber.Ctx) error {
c.WriteString("Hello, World!") // => "Hello, World!"
fmt.Fprintf(c, "%s\n", "Hello, World!") // "Hello, World!Hello, World!"
})
XHR
一个布尔属性,如果请求的X-Requested-With标头字段是XMLHttpRequest,则为true
,表示请求是由客户端库(如jQuery)发出的。
func (c *Ctx) XHR() bool
// X-Requested-With: XMLHttpRequest
app.Get("/", func(c *fiber.Ctx) error {
c.XHR() // true
// ...
})
XML
使用标准的encoding/xml
包将任何接口或字符串转换为 XML。
XML 也将内容标头设置为application/xml。
func (c *Ctx) XML(data interface{}) error
type SomeStruct struct {
XMLName xml.Name `xml:"Fiber"`
Name string `xml:"Name"`
Age uint8 `xml:"Age"`
}
app.Get("/", func(c *fiber.Ctx) error {
// Create data struct:
data := SomeStruct{
Name: "Grame",
Age: 20,
}
return c.XML(data)
// <Fiber>
// <Name>Grame</Name>
// <Age>20</Age>
// </Fiber>
})