在echo框架中中間件(Middleware)指的是可以攔截http請求-響應生命周期的特殊函數,在請求-響應生命周期中可以注冊多個中間件,每個中間件執行不同的功能,一個中間執行完再輪到下一個中間件執行。
中間件是一個函數,嵌入在HTTP 的請求和響應之間。它可以獲得 Echo#Context
對象用來進行一些特殊的操作, 比如記錄每個請求或者統計請求數。
Action的處理在所有的中間件運行完成之后。
更多中間件參考官方文檔golang echo:https://echo.labstack.com/middleware
中間件的常見應用場景如下:
- 請求限速
- api接口簽名處理
- 權限校驗
- 統一錯誤處理
提示:如果想攔截所有請求做一些事情都,可開發一個中間件函數去實現。
1.中間件級別
Root Level (Before router)
Echo#Pre()
用於注冊一個在路由執行之前運行的中間件,可以用來修改請求的一些屬性。比如在請求路徑結尾添加或者刪除一個’/‘來使之能與路由匹配。
下面的這幾個內建中間件應該被注冊在這一級別:
- AddTrailingSlash
- RemoveTrailingSlash
- MethodOverride
注意: 由於在這個級別路由還沒有執行,所以這個級別的中間件不能調用任何 echo.Context
的 API。
Root Level (After router)
大部分時間你將用到 Echo#Use()
在這個級別注冊中間件。 這個級別的中間件運行在路由處理完請求之后,可以調用所有的 echo.Context
API。
2.常用中間件
下面介紹echo自帶的中間件
2.1. Redirect
HTTPS 重定向
HTTPS 重定向中間件將 http 請求重定向到 https。例如,http://laily.net 將被重定向到 https://laily.net。
用法
e := echo.New()
e.Pre(middleware.HTTPSRedirect())
HTTPS WWW 重定向
HTTPS WWW 重定向將 http 請求重定向到帶 www 的 https 請求。例如,http://laily.net 將被重定向到 https://www.laily.net。
用法
e := echo.New()
e.Pre(middleware.HTTPSWWWRedirect())
HTTPS NonWWW 重定向
HTTPS NonWWW 將 http 請求重定向到不帶 www 的 https 請求。例如,http://www.laily.net 將被重定向到 https://laily.net。
用法
e := echo.New()
e.Pre(middleware.HTTPSNonWWWRedirect())
WWW 重定向
WWW 重定向將不帶 www 的請求重定向到帶 www 的請求。
例如,http://laily.net 重定向到 http://www.laily.net
用法
e := echo.New()
e.Pre(middleware.WWWRedirect())
NonWWW 重定向
NonWWW 重定向將帶 www 的請求重定向到不帶 www 的請求。
例如,http://www.laily.net 重定向到 http://laily.net
用法
e := echo.New()
e.Pre(middleware.NonWWWRedirect())
2.2. Recover
Recover中間件,主要用於攔截panic錯誤並且在控制台打印錯誤日志,避免echo程序直接崩潰。
使用例子:
//初始化echo實例
e := echo.New()
//注冊中間件
e.Use(middleware.Recover())
提示:一般echo應用都會注冊Recover中間件,避免程序崩潰退出。
2.3. Static
Static中間件主要用於處理js、css之類的靜態資源, 具體用法請參考: 處理靜態文件。
2.4. Logger
Logger中間件主要用於打印http請求日志。
//初始化echo實例
e := echo.New()
//注冊中間件
e.Use(middleware.Logger())
開啟Logger中間件后,訪問http請求會打印出日志:
2.5. Rewrite
url重定向中間,可以用於將一個url重定向到另外一個url。
例子:
//初始化echo實例
e := echo.New()
e.Pre(middleware.Rewrite(map[string]string{
"/old": "/new", //將/old重定向至/new
"/api/*": "/$1",
"/js/*": "/public/javascripts/$1",
"/users/*/orders/*": "/user/$1/order/$2",
}))
/api/*代表任意字符串,$1 代表引用表達式中第一個*的匹配值, $2代表第二個,以此類推。
3.自定義中間件
下面以一個簡單的統計訪問量的例子介紹如何自定義中間件。
package main
import (
"net/http"
"github.com/labstack/echo"
)
//記錄訪問量
var totalRequests = 0
//中間件函數
func Count(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
//在這里處理攔截請求的邏輯
//累計訪問量
totalRequests++
//在響應頭中輸出訪問量
c.Response().Header().Add("requests", fmt.Sprintf("%d", totalRequests))
//執行下一個中間件或者執行控制器函數, 然后返回執行結果
return next(c)
}
}
func main() {
//初始化echo實例
e := echo.New()
//注冊中間件
e.Use(Count)
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.Logger.Fatal(e.Start(":1323"))
}
4.自定義配置
用法
e := echo.New()
e.Use(middleware.HTTPSRedirectWithConfig(middleware.RedirectConfig{
Code: http.StatusTemporaryRedirect,
}))
上面的示例將 HTTP 的請求重定向到 HTTPS,使用 307 - StatusTemporaryRedirect
狀態碼跳轉。
配置
RedirectConfig struct {
// Skipper defines a function to skip middleware.
Skipper Skipper
// Status code to be used when redirecting the request.
// Optional. Default value http.StatusMovedPermanently.
Code int `json:"code"`
}
默認配置
DefaultRedirectConfig = RedirectConfig{
Skipper: defaultSkipper,
Code: http.StatusMovedPermanently,
}