注册 登录

清河洛

fiber中Context对象的用法

qingheluo2023-11-10清河洛649
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头将...

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")
})


网址导航