跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 适用于 Gin 和 net/http 的 gzip 中间件,基于 Content-Type、Content-Length、扩展名等要素自动判断是否启用压缩
未分類
11 6 月 2020

适用于 Gin 和 net/http 的 gzip 中间件,基于 Content-Type、Content-Length、扩展名等要素自动判断是否启用压缩

适用于 Gin 和 net/http 的 gzip 中间件,基于 Content-Type、Content-Length、扩展名等要素自动判断是否启用压缩

資深大佬 : nanmu42 64

gzip 中间件

项目地址: https://github.com/nanmu42/gzip

适用于Gin和net/http的 gzip 中间件。基于 Content-Type、Content-Length、扩展名等要素自动判断是否启用压缩。

使用示例

适用于 Gin 和 net/http 的 gzip 中间件,基于 Content-Type、Content-Length、扩展名等要素自动判断是否启用压缩

Gin

import github.com/nanmu42/gzip  func main() {  g := gin.Default()       // 使用默认设定  g.Use(gzip.DefaultHandler().Gin)   g.GET("/", func(c *gin.Context) {   c.JSON( http.StatusOK, map[string]interface{}{    "code": 0,    "msg":  "hello",    "data": fmt.Sprintf("l%sng!", strings.Repeat("o", 1000)),   })  })   log.Println(g.Run(fmt.Sprintf(":%d", 3000))) } 

net/http

import github.com/nanmu42/gzip  func main() {  mux := http.NewServeMux()  mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {   writeString(w, fmt.Sprintf("This content is compressed: l%sng!", strings.Repeat("o", 1000)))  })      // 使用默认设定  log.Println( http.ListenAndServe(fmt.Sprintf(":%d", 3001), gzip.DefaultHandler().WrapHandler(mux))) }  func writeString(w http.ResponseWriter, payload string) {  w.Header().Set("Content-Type", "text/plain; charset=utf8")  _, _ = io.WriteString(w, payload+"n") } 

定制Handler

在创建Handler时,可以定制参数以满足你的需要:

import github.com/nanmu42/gzip  handler := gzip.NewHandler(gzip.Config{     // gzip 压缩等级  CompressionLevel: 6,     // 使用 gzip 的最小 body 体积,单位:byte  MinContentLength: 256,     // 请求过滤器基于请求来判断是否对这条请求的返回启用 gzip,     // 过滤器按其定义顺序执行,下同。  RequestFilter: []RequestFilter{      NewCommonRequestFilter(),      DefaultExtensionFilter(),  },     // 返回 header 过滤器基于返回的 header 判断是否对这条请求的返回启用 gzip  ResponseHeaderFilter: []ResponseHeaderFilter{   NewSkipCompressedFilter(),   DefaultContentTypeFilter(),  }, }) 

RequestFilter 和 ResponseHeaderFilter 是 interface. 你可以实现你自己的过滤器。

Handler 的局限性

  • 总是在返回中提供Content-Type,Handler 不会对未知Content-Type的返回进行类型猜测;
  • Handler 会先在返回的 Content-Length 中查询 body 体积,如果没有就再查看http.ResponseWriter.Write(data []byte)在首次调用时的 len(data)作为参考。倘若返回的 Content-Length不存在,且http.ResponseWriter.Write(data []byte)首次调用时的len(data)较小,这条返回会被错误认为无需压缩。

如果你使用的是 Gin 的c.JSON()或c.PureJSON(),无需担心上述问题。

如果你直接使用net/http,请妥善处理上述问题。

大佬有話說 (2)

  • 資深大佬 : missdeer

    让前置 nginx 处理如何?

  • 主 資深大佬 : nanmu42

    @missdeer 当返回的 JSON 大于 2KB 时,Golang 会使用 chunk 的形式传输,这个时候没有`Content-Length`,Nginx 的 `ngx_http_gzip_module` 的 `gzip_min_length` 仅从 `Content-Length` 判断是否压缩,导致内容不被压缩。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具