猿问

使用代理中间件的 Echo CORS 会导致使用 Access-Allow-Origins

我正在使用 LabStack 的 Golang Echo 框架来构建服务。

其中一种路由需要代理来自后端服务的请求和响应。

但我也需要 CORS 来处理这项服务。

所以我在请求/响应堆栈中使用middleware.CORSWithConfigw/a 。middleware.ProxyWithConfig

我发现标头有些奇怪Access-Control-Allow-Origins,其中从代理服务到我的 Echo 服务器的响应中该标头的值*,但是一旦它通过代理,*, *当它返回客户端时它就会更改为 。之后我开始看到以下与 CORS 违规相关的浏览器错误:

VM1627:362 Access to XMLHttpRequest at 'http://localhost:6273/' from origin 'http://localhost:8002' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.

有人遇到过这个吗?任何人都知道为什么会发生这种情况以及可能有解决方法吗?

这是一些示例代码:

package main


func singleTargetBalancer(url *url.URL) middleware.ProxyBalancer {

    targetURL := []*middleware.ProxyTarget{

        {

            URL: url,

        },

    }

    return middleware.NewRoundRobinBalancer(targetURL)

}


func Noop(ctx echo.Context) (err error) {

    ctx.String(

        http.StatusNotImplemented,

        "No op handler should never be reached!",

    )


    return err

}


func main() {

        e := echo.New()

    e.HideBanner = true

    e.Use(

        middleware.CORSWithConfig(middlewares.CustomCorsConfig),

        middlewares.ThriftMetrics(),

    )


        // Have to use a Noop handler since we're not trying to set up a full-on proxy for the backend service.  We only want this one route to be proxied.

        e.POST(

        "/",

        handlers.Noop,

        middleware.ProxyWithConfig(middleware.ProxyConfig{

             Balancer: singleTargetBalancer("[backend service URL]"),

            })

    )

}


FFIVE
浏览 125回答 1
1回答

紫衣仙女

我最终通过编写一个自定义的 Echo 中间件来解决这个问题,以便在 Echo 的代理中间件将标头发送回客户端之前挂钩到响应。func setResponseACAOHeaderFromRequest (req http.Request, resp echo.Response) {    resp.Header().Set(echo.HeaderAccessControlAllowOrigin,     req.Header.Get(echo.HeaderOrigin))}func ACAOHeaderOverwriteMiddleware(next echo.HandlerFunc) echo.HandlerFunc {    return func(ctx echo.Context) error {        ctx.Response().Before(func() {            setResponseACAOHeaderFromRequest(*ctx.Request(), *ctx.Response())        })        return next(ctx)    }}然后将此中间件放在e.Use() 代理中间件之前:e.POST(        "/",        handlers.Noop,        ACAOHeaderOverwriteMiddleware,        middleware.ProxyWithConfig(middleware.ProxyConfig{             Balancer: singleTargetBalancer("[backend service URL]"),        }))Request::Before()Echo钩子的文档: https ://echo.labstack.com/guide/response#before-response
随时随地看视频慕课网APP

相关分类

Go
我要回答