代码 Gin 框架的中间件 代码压缩

2024-11-19 08:23:48 +0800 CST views 779

这段代码是一个基于 Gin 框架的中间件,用于压缩和最小化 HTML 和 JavaScript 内容。它通过将原始响应内容传递给 tdewolff/minify 库来实现内容的压缩,最终返回最小化后的内容,减小响应体积,从而提高页面加载速度。

主要功能点

  1. HTML 和 JavaScript 最小化

    • 使用 tdewolff/minify 库,分别为 text/htmltext/javascript(包括 application/javascript)设置了相应的压缩处理器。
    • 中间件根据响应的 Content-Type 自动选择是否压缩响应内容。
  2. 自定义响应处理

    • 通过自定义 ResponseWriter 来捕获原始响应内容,延迟处理并根据情况压缩内容。
    • 只有在确定 Content-Type 之后,才会写入 HTTP 状态码和响应头部信息,确保正确计算内容长度。
  3. 错误处理

    • 如果最小化过程中发生错误,返回 500 错误并在响应中附带错误信息。

代码

package middlewares

import (
	"bytes"
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/tdewolff/minify/v2"
	"github.com/tdewolff/minify/v2/html"
	"github.com/tdewolff/minify/v2/js"
)

// HTMLMinifier creates a middleware to minify HTML and JavaScript content.
func HTMLMinifier() gin.HandlerFunc {
	m := minify.New()
	htmlMinifier := html.Minifier{
		KeepDocumentTags: true, // Ensures that <html> and <body> tags are preserved
	}
	m.Add("text/html", &htmlMinifier)
	m.AddFunc("text/javascript", js.Minify)
	m.AddFunc("application/javascript", js.Minify)

	return func(c *gin.Context) {
		buf := new(bytes.Buffer)
		originalWriter := c.Writer
		c.Writer = &customResponseWriter{
			ResponseWriter: originalWriter,
			body:           buf,
		}

		c.Next() // Process the request

		contentType := c.Writer.Header().Get("Content-Type")
		fmt.Println("Content-Type:", contentType)
		switch {
		case contentType == "text/html; charset=utf-8":

			minifiedContent, err := m.String("text/html", buf.String())
			handleMinification(c, originalWriter, minifiedContent, err)
		case contentType == "text/javascript", contentType == "application/javascript":
			minifiedContent, err := m.String(contentType, buf.String())
			handleMinification(c, originalWriter, minifiedContent, err)
		default:
			// For other types, write the original buffer
			originalWriter.WriteHeader(http.StatusOK)
			originalWriter.Write(buf.Bytes())
		}
		buf.Reset() // Clear the buffer to prevent any further automatic output
	}
}

// handleMinification handles the output of minified content.
func handleMinification(c *gin.Context, w http.ResponseWriter, minifiedContent string, err error) {
	if err != nil {
		c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "Error minifying content"})
		return
	}
	w.Header().Del("Content-Length") // Let Gin recalculate Content-Length
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(minifiedContent))
}

// customResponseWriter wraps an http.ResponseWriter to capture writes for minification.
type customResponseWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer
}

func (w *customResponseWriter) Write(data []byte) (int, error) {
	// Write to the buffer only, not to the ResponseWriter directly
	return w.body.Write(data)
}

func (w *customResponseWriter) WriteHeader(statusCode int) {
	// Delay writing the header until content type is checked and possibly modified
	if !w.Written() {
		w.ResponseWriter.WriteHeader(statusCode)
	}
}

使用方法

  1. 将此中间件添加到 Gin 的路由中:

    r := gin.Default()
    r.Use(middlewares.HTMLMinifier())
    
  2. 在路由处理函数中返回 HTML 或 JavaScript 内容,中间件会自动处理并压缩这些内容。

代码结构

  • HTMLMinifier 函数:创建和配置 HTML 和 JavaScript 的压缩器。
  • handleMinification 函数:处理压缩后的内容输出。
  • customResponseWriter 结构体:自定义的响应写入器,用于捕获和延迟响应内容的输出。

该中间件可显著减少 HTML 和 JavaScript 的响应大小,适用于需要优化前端性能的应用。
images

复制全文 生成海报 Web开发 性能优化 中间件 Go语言 前端

推荐文章

Go语言中的mysql数据库操作指南
2024-11-19 03:00:22 +0800 CST
Python 微软邮箱 OAuth2 认证 Demo
2024-11-20 15:42:09 +0800 CST
CSS实现亚克力和磨砂玻璃效果
2024-11-18 01:21:20 +0800 CST
智能视频墙
2025-02-22 11:21:29 +0800 CST
Vue3中如何实现状态管理?
2024-11-19 09:40:30 +0800 CST
# 解决 MySQL 经常断开重连的问题
2024-11-19 04:50:20 +0800 CST
MySQL设置和开启慢查询
2024-11-19 03:09:43 +0800 CST
一些实用的前端开发工具网站
2024-11-18 14:30:55 +0800 CST
html一些比较人使用的技巧和代码
2024-11-17 05:05:01 +0800 CST
SQL常用优化的技巧
2024-11-18 15:56:06 +0800 CST
PHP 代码功能与使用说明
2024-11-18 23:08:44 +0800 CST
Redis函数在PHP中的使用方法
2024-11-19 04:42:21 +0800 CST
一些好玩且实用的开源AI工具
2024-11-19 09:31:57 +0800 CST
Vue3 组件间通信的多种方式
2024-11-19 02:57:47 +0800 CST
mysql 优化指南
2024-11-18 21:01:24 +0800 CST
mysql 计算附近的人
2024-11-18 13:51:11 +0800 CST
mysql关于在使用中的解决方法
2024-11-18 10:18:16 +0800 CST
PyMySQL - Python中非常有用的库
2024-11-18 14:43:28 +0800 CST
Vue3中如何处理路由和导航?
2024-11-18 16:56:14 +0800 CST
robots.txt 的写法及用法
2024-11-19 01:44:21 +0800 CST
Vue3中如何处理WebSocket通信?
2024-11-19 09:50:58 +0800 CST
H5抖音商城小黄车购物系统
2024-11-19 08:04:29 +0800 CST
支付宝批量转账
2024-11-18 20:26:17 +0800 CST
FastAPI 入门指南
2024-11-19 08:51:54 +0800 CST
程序员茄子在线接单