跨域(CORS)

go-zero 针对跨域提供了三种用法:

  • rest.WithCors(origin ...string)
    • 设置允许跨域的域名
  • rest.WithCorsHeaders(headers ...string)
    • 设置允许跨域的 header
  • rest.WithCustomCors(middlewareFn func(header http.Header), notAllowedFn func(http.ResponseWriter), origin ...string)
    • 设置复杂的跨域需求

如何自定义跨域 header

可以通过 go-zerorest.WithCorsHeaders(headers ...string) 增加允许跨域的 header

示例代码如下:

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/zeromicro/go-zero/core/conf"
  6. "github.com/zeromicro/go-zero/core/logx"
  7. "github.com/zeromicro/go-zero/rest"
  8. "github.com/zeromicro/go-zero/rest/httpx"
  9. )
  10. func main() {
  11. var c rest.RestConf
  12. conf.MustLoad("config.yaml", &c)
  13. server := rest.MustNewServer(c, rest.WithCorsHeaders("UserHeader1", "UserHeader2"))
  14. defer server.Stop()
  15. server.AddRoutes(
  16. []rest.Route{
  17. {
  18. Method: http.MethodPost,
  19. Path: "/test",
  20. Handler: func(w http.ResponseWriter, r *http.Request) {
  21. logx.Info("请求进来了")
  22. httpx.OkJsonCtx(r.Context(), w, "1")
  23. },
  24. },
  25. },
  26. )
  27. fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
  28. server.Start()
  29. }

go-zero 版本:>= v1.7.1

如何自定义跨域 domain?

可以通过 go-zerorest.WithCors(origins ...string) 设置允许跨域的域名。

示例代码如下:

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/zeromicro/go-zero/core/conf"
  6. "github.com/zeromicro/go-zero/core/logx"
  7. "github.com/zeromicro/go-zero/rest"
  8. "github.com/zeromicro/go-zero/rest/httpx"
  9. )
  10. func main() {
  11. var c rest.RestConf
  12. conf.MustLoad("config.yaml", &c)
  13. // 设置允许跨域的域名
  14. server := rest.MustNewServer(c, rest.WithCors("example.com"))
  15. defer server.Stop()
  16. server.AddRoutes(
  17. []rest.Route{
  18. {
  19. Method: http.MethodPost,
  20. Path: "/test",
  21. Handler: func(w http.ResponseWriter, r *http.Request) {
  22. logx.Info("请求进来了")
  23. httpx.OkJsonCtx(r.Context(), w, "1")
  24. },
  25. },
  26. },
  27. )
  28. fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
  29. server.Start()
  30. }

如何自定义复杂的跨域设置?

可以通过 go-zerorest.WithCustomCors 设置复杂的跨域行为。

示例代码如下:

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "github.com/zeromicro/go-zero/core/conf"
  6. "github.com/zeromicro/go-zero/core/logx"
  7. "github.com/zeromicro/go-zero/rest"
  8. "github.com/zeromicro/go-zero/rest/httpx"
  9. )
  10. func main() {
  11. var c rest.RestConf
  12. conf.MustLoad("config.yaml", &c)
  13. server := rest.MustNewServer(c, rest.WithCustomCors(func(header http.Header) {
  14. header.Set("Access-Control-Allow-Origin", "*")
  15. header.Add("Access-Control-Allow-Headers", "UserHeader1, UserHeader2")
  16. header.Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH")
  17. header.Set("Access-Control-Expose-Headers", "Content-Length, Content-Type")
  18. }, nil, "*"))
  19. defer server.Stop()
  20. server.AddRoutes(
  21. []rest.Route{
  22. {
  23. Method: http.MethodPost,
  24. Path: "/test",
  25. Handler: func(w http.ResponseWriter, r *http.Request) {
  26. logx.Info("请求进来了")
  27. httpx.OkJsonCtx(r.Context(), w, "1")
  28. },
  29. },
  30. },
  31. )
  32. fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
  33. server.Start()
  34. }

自定义复杂的跨域设置示例

示例代码如下:

  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "github.com/zeromicro/go-zero/core/logx"
  8. "github.com/zeromicro/go-zero/core/conf"
  9. "github.com/zeromicro/go-zero/rest"
  10. "github.com/zeromicro/go-zero/rest/httpx"
  11. )
  12. var configFile = flag.String("f", "etc/core-api-dev.yaml", "the config file")
  13. func main() {
  14. flag.Parse()
  15. var c config.Config
  16. conf.MustLoad(*configFile, &c)
  17. # 需要通过的域名,这里可以写多个域名 或者可以写 * 全部通过
  18. domains := []string{"*","http://127.0.0.1", "https://go-zero.dev", "http://localhost"}
  19. server := rest.MustNewServer(
  20. c.RestConf,
  21. rest.WithCors(domains...),
  22. rest.WithCustomCors(func(header http.Header) {
  23. # 这里写允许通过的header key 不区分大小写
  24. header.Add("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token,Authorization,Token,X-Token,X-User-Id,OS,Platform, Version")
  25. header.Set("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS,PATCH")
  26. header.Set("Access-Control-Expose-Headers", "Content-Length, Content-Type")
  27. }, nil, "*"),
  28. )
  29. defer server.Stop()
  30. ctx := svc.NewServiceContext(c)
  31. handler.RegisterHandlers(server, ctx)
  32. fmt.Printf("Starting admin_user-api server at %s:%d...\n", c.Host, c.Port)
  33. server.Start()
  34. }