pattern:源路径target:目标路径(转发到的url)
若希望将/api代理到http://localhost/v1/api,则pattern为/api,target为http://localhost/v1/api
这里使用echo框架
// ServeProxy 代理服务
func ServeProxy(e *echo.Echo, pattern string, target string) {
targetUrl, err := url.Parse(target)
if err != nil {
log.Println(err)
return
}
proxy := &httputil.ReverseProxy{
// 重写 request.Out.URL 为目标路径
Rewrite: func(request *httputil.ProxyRequest) {
request.Out.URL.Scheme = targetUrl.Scheme
request.Out.URL.Host = targetUrl.Host
request.Out.URL.Path = path.Join(targetUrl.Path, strings.TrimPrefix(request.In.URL.Path, pattern))
},
// 对响应进行处理,可不写
ModifyResponse: func(response *http.Response) error {
response.Header.Del("X-Frame-Options")
response.Header.Del("X-XSS-Protection")
response.Header.Del("X-Content-Type-Options")
// 若后端已经配置了这些响应头,则删掉,防止重复配置
response.Header.Del("Access-Control-Allow-Origin")
response.Header.Del("Access-Control-Allow-Methods")
response.Header.Del("Access-Control-Allow-Headers")
response.Header.Del("Access-Control-Allow-Credentials")
response.Header.Del("Access-Control-Max-Age")
response.Header.Del("Access-Control-Expose-Headers")
return nil
},
}
// 处理所有前缀为 pattern 的路由,若使用标准库,可写成 pattern+"/"
e.Any(pattern+"*", func(context echo.Context) error {
// 若使用标准库,则直接传res,req
proxy.ServeHTTP(context.Response(), context.Request())
return nil
})
}