首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >CORS grpc网关GoLang

CORS grpc网关GoLang
EN

Stack Overflow用户
提问于 2022-11-20 18:31:00
回答 3查看 106关注 0票数 3

我有一个vue.js 3前端,我通过grpc-gateway调用一个Golang后端。我在这方面已经有一段时间了,但我在隧道的尽头看到了光明。

我目前正面临一个CORS问题。然而,我正在阅读关于如何处理它的相互矛盾的信息。因此,我想发帖,希望它能帮助到一些人。

下面是我如何为GRPC (网关)安装我的mux服务器的代码

代码语言:javascript
运行
复制
func RunHttpServer(server *http.Server, httpEndpoint, grpcEndpoint, swaggerPath string) (err error) {
    server.Addr = httpEndpoint

    ctx, cancel := context.WithCancel(context.Background())

    defer cancel()

    // Register gROC server endpoint
    mux := runtime.NewServeMux(
        runtime.WithErrorHandler(func(ctx context.Context,
            mux *runtime.ServeMux,
            marshaler runtime.Marshaler,
            w http.ResponseWriter, r *http.Request,
            err error,
        ) {
            s, ok := status.FromError(err)
            if ok {
                if s.Code() == codes.Unavailable {
                    err = status.Error(codes.Unavailable, ErrUnavailable)
                }
            }

            runtime.DefaultHTTPErrorHandler(ctx, mux, marshaler, w, r, err)

        }),
    )

    opts := []grpc.DialOption{
        grpc.WithTransportCredentials(insecure.NewCredentials()),
        grpc.WithChainUnaryInterceptor(),
    }

    if err = api.RegisterApiServiceHandlerFromEndpoint(ctx, mux, grpcEndpoint, opts); err != nil {
        return
    }

    swMux := http.NewServeMux()
    swMux.Handle("/", mux)
    serveSwagger(swMux, swaggerPath)

    server.Handler = swMux

    return server.ListenAndServe()

}

这里是我认为应该添加cors配置的地方,但我不确定我是如何在server.go文件中设置它的。

代码语言:javascript
运行
复制
var httpServer http.Server

// Run Http Server with gRPC gateway
g.Go(func() error {
    fmt.Println("Starting Http sever (port {}) and gRPC gateway (port {})",
        strconv.Itoa(cfg.Server.HTTPPort),
        strconv.Itoa(cfg.Server.GRPCPort),
    )

    return rest.RunHttpServer(
        &httpServer,
        ":"+strconv.Itoa(cfg.Server.HTTPPort),
        ":"+strconv.Itoa(cfg.Server.GRPCPort),
        "/webapi",
    )
})

控制台中的错误:

代码语言:javascript
运行
复制
Access to XMLHttpRequest at 'http://localhost:8080/v1/test' from origin 'http://localhost:9000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin'

我不知道该在哪里添加这样的东西

代码语言:javascript
运行
复制
func enableCors(w *http.ResponseWriter) {
    (*w).Header().Set("Access-Control-Allow-Origin", "*")
}

我觉得金刚GRPC网关应该有内置的东西,但我什么也找不到?

如有任何建议,将不胜感激。

更新1

我试过了

代码语言:javascript
运行
复制
func enableCors(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "http://localhost:9000")
        w.Header().Set("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, HEAD, OPTIONS")
        h.ServeHTTP(w, r)
    })
}

代码语言:javascript
运行
复制
func enableCors(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, HEAD, OPTIONS")
        h.ServeHTTP(w, r)
    })
}

代码语言:javascript
运行
复制
func enableCors(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "http://localhost")
        w.Header().Set("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, HEAD, OPTIONS")
        h.ServeHTTP(w, r)
    })
}

与.

代码语言:javascript
运行
复制
func serveSwagger(mux *http.ServeMux, swaggerPath string) {
    fileServer := http.FileServer(http.Dir(swaggerPath))
    prefix := "/swagger-ui"
    mux.Handle(prefix, http.StripPrefix(prefix, fileServer))
}

还有同样的问题..。非常令人沮丧

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-11-25 11:46:17

根据您在评论中提供的最新错误:

从源“localhost:8080/v1/test”访问XMLHttpRequest的权限已被CORS策略阻止:对飞行前请求的响应不通过访问控制检查:它没有HTTP状态。

您的浏览器正在发送一个飞行前请求 (OPTIONS HTTP方法),以确定是否可以提出所需的跨源请求。

服务器用非2xx响应进行响应。

我怀疑这是因为您的enableCors函数将请求传播到grpc网关处理程序,而grpc网关处理程序对OPTIONS HTTP方法不满意并返回错误状态,可能是:

代码语言:javascript
运行
复制
< HTTP/1.1 501 Not Implemented
< Content-Type: application/json
< Vary: Origin
< Date: Fri, 25 Nov 2022 11:17:52 GMT
< Content-Length: 55
< 
{"code":12,"message":"Method Not Allowed","details":[]}

因此,为了避免这种情况,在提出飞行前请求的情况下,您不希望进一步传播请求。

代码语言:javascript
运行
复制
func enableCors(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "http://localhost:9000")
        w.Header().Set("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, HEAD, OPTIONS")
        if r.Method == http.MethodOptions {
            w.WriteHeader(http.StatusNoContent)
            return
        }
        h.ServeHTTP(w, r)
    })
}

然而,上述可能仍然不是CORS处理的合理实现。您应该为此使用一个现有的包,例如github.com/rs/cors,它将以合理的方式处理这个问题,并处理任何潜在的问题,等等。

因此,导入github.com/rs/cors,然后执行如下操作:

代码语言:javascript
运行
复制
server.Handler = cors.AllowAll().Handler(swMux)

应该让你开始让一切都过去。库将允许您根据需要定制特定的源、HTTP方法等。

票数 1
EN

Stack Overflow用户

发布于 2022-11-22 19:58:29

一种方法是使用附加的处理程序逻辑丰富swMux

代码语言:javascript
运行
复制
func enableCors(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")

        h.ServeHTTP(w, r)
    })
}

然后,在您的RunHttpServer函数中调用它:

代码语言:javascript
运行
复制
swMux := http.NewServeMux()
swMux.Handle("/", mux)
serveSwagger(swMux, swaggerPath)

server.Handler = enableCors(swMux)

这里是另一个启用了更多选项的示例。这里grpc-gateway回购公司关于如何处理CORS的一个官方例子。

票数 1
EN

Stack Overflow用户

发布于 2022-11-25 09:59:52

如果您正在本地调试,则应将代理添加到前端到后端服务的代理。应该有一个vue.config.js文件

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74510810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档