🧠 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
// ...
})
支持 Media-Type 参数。
// 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 头提供了类似的功能。
// 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", "http://localhost")
// => Link: http://localhost, http://google.com
c.Append("Link", "Test")
// => Link: http://localhost, http://google.com, Test
// ...
})
Attachment
将 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
以 string
类型返回基本 URL(协议 + 主机)。
func (c *Ctx) BaseURL() string
// GET https://example.com/page#chapter-1
app.Get("/", func(c *fiber.Ctx) error {
c.BaseURL() // https://example.com
// ...
})
Bind
将变量添加到默认视图变量映射,绑定到模板引擎。变量由 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 http://localhost: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")
})
Body
根据 Content-Encoding
头,此方法将尝试对请求体字节进行文件解压缩。如果未发送 Content-Encoding
头,则行为与 BodyRaw 相同。
func (c *Ctx) Body() []byte
// echo 'user=john' | gzip | curl -v -i --data-binary @- -H "Content-Encoding: gzip" http://localhost: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 | form |
multipart/form-data | form |
application/json | json |
application/xml | xml |
text/xml | xml |
处理 multipart/form-data
时,只有表单值可以直接分配给结构体字段。请求中包含的文件不会自动分配给结构体。必须使用 FormFile
或其他文件特定方法单独处理文件。
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 http://localhost:3000
// curl -X POST "http://localhost: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")
// ...
})
Web 浏览器和其他兼容的客户端只有在给定的选项(不包括 expires 和 maxAge)与创建 cookie 时相同的情况下,才会清除 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
返回兼容 context.Context 接口的 *fasthttp.RequestCtx,该接口需要在 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" http://localhost: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 请求头作为 map 返回。由于单个请求中的一个头可以设置多次,map 的值是包含该头所有不同值的字符串切片。
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 响应头作为 map 返回。由于单个请求中的一个头可以设置多次,map 的值是包含该头所有不同值的字符串切片。
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,
})
IPs
返回 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 包将任何 interface 或 string 转换为 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 回调。默认情况下,回调名称仅为 callback。
通过在方法中传递一个命名字符串来覆盖此设置。
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
此方法存储作用域限定于请求的变量,因此仅对匹配该请求的路由可用。存储的变量在请求处理后被移除。如果任何存储的数据实现了 io.Closer
接口,则在移除前会调用其 Close
方法。
如果您想将某些特定数据传递给下一个中间件,这将很有用。请记住在检索数据时进行类型断言,以确保其类型符合预期。您还可以使用非导出类型作为键来避免冲突。
func (c *Ctx) Locals(key interface{}, value ...interface{}) interface{}
type keyType struct{}
var userKey keyType
app.Use(func(c *fiber.Ctx) error {
c.Locals(userKey, "admin") // Stores the string "admin" under a non-exported type key
return c.Next()
})
app.Get("/admin", func(c *fiber.Ctx) error {
user, ok := c.Locals(userKey).(string) // Retrieves the data stored under the key and performs a type assertion
if ok && 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
})
Method
返回与请求的 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"
// ...
})
Protocol
包含请求协议字符串:http
或 TLS 请求的 https
。
func (c *Ctx) Protocol() string
// GET http://example.com
app.Get("/", func(c *fiber.Ctx) error {
c.Protocol() // "http"
// ...
})
Queries
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
})
Query
此属性是一个对象,包含路由中每个查询字符串参数的属性,您可以传递一个可选的默认值,如果查询键不存在,将返回该默认值。
如果没有查询字符串,则返回一个空字符串。
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 "http://localhost: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 Found。
当重定向状态码为 302 Found 时,Web 浏览器可能会根据其实现更改 HTTP 方法(例如,将 POST 转换为 GET)。为了确保原始 HTTP 方法得到保留,特别是在需要非 GET 方法的情况下,您应该明确使用以下状态码之一
- 303 See Other
- 307 Temporary Redirect
- 308 Permanent Redirect
例如,要保留 HTTP 方法,请使用
c.Redirect("/new-path", fiber.StatusSeeOther)
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 Found。
如果要将查询发送到路由,必须向 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。如果 refer 头不存在,则重定向到备用 URL,并带有指定的 HTTP 状态码(一个正整数)。
如果未指定,状态默认为 302 Found。
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 "http://localhost: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
// http://localhost: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
此方法用于将任何 multipart 文件保存到磁盘。
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
此方法用于将任何 multipart 文件保存到外部存储系统。
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 响应头字段。
此方法默认不使用 gzipping,将其设置为 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 http://localhost:3000/body
// curl -X GET "http://localhost:3000/query?title=title&body=body&date=2021-10-20"
SetUserContext
为 context 接口设置用户指定的实现。
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 状态。
此方法是链式的。
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
返回请求域名中的子域名字符串切片。
应用程序属性 subdomain offset(默认为 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 返回用户之前设置的 context 实现,如果未设置,则返回一个非 nil 的空 context。
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
包将任何 interface 或 string 转换为 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>
})