dongshi2141 2015-05-19 12:21
浏览 178
已采纳

Golang + CORS。 全球设置不知何故?

I'm trying out this small Go example https://github.com/jakecoffman/golang-rest-bootstrap, and so far so good.

I'm trying to add CORS to allow my front-end app access.

Here is my Main.go

func main() {

    var err error

    session, err = r.Connect(r.ConnectOpts{
        Address:  "localhost:28015",
        Database: "demo",
        MaxOpen:  40,
    })
    if err != nil {
        log.Fatalln(err.Error())
    }

    r := mux.NewRouter()
    users.Init(r, session)
    accounts.Init(r, session)

    r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
    })

    port := "9999" // os.Getenv("PORT")
    log.Println("Serving on", ":"+port)
    http.ListenAndServe(":"+port, context.ClearHandler(r))
}

It allows CORS at the root url, but since the other routes are handled in the controllers I just can't seem to get CORS to work there as well.

Here is part of the AccountController

func NewAccountController(r *mux.Router, s AccountService) *AccountController {
    cont := AccountController{s}
    r.Handle("/accounts", cont)
    r.Handle("/accounts/{id}", cont)

    return &cont
}

And

func (a AccountController) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    code := http.StatusMethodNotAllowed
    var data interface{}

    defer func(c int) {
        log.Println(r.URL, "-", r.Method, "-", code, r.RemoteAddr)
    }(code)

    if r.URL.Path == "/accounts" {
        switch r.Method {
        case "GET":
            code, data = a.List(w, r)
        case "POST":
            code, data = a.Add(w, r)
        default:
            return
        }
    } else {
        switch r.Method {
        case "GET":
            code, data = a.Get(w, r)
        case "PUT":
            code, data = a.Update(w, r)
        case "DELETE":
            code, data = a.Delete(w, r)
        default:
            return
        }
    }

    w.WriteHeader(code)
    w.Header().Set("Content-Type", "application/json")

    err := json.NewEncoder(w).Encode(data)
    if err != nil {
        log.Println("Failed to write data: ", err)
        code = http.StatusInternalServerError
    }
}

Any ideas or pointers would be great.

Thanks,

JB

  • 写回答

1条回答 默认 最新

  • dpz90118 2015-05-19 12:32
    关注

    You can make a simple middleware for that:

    type CORSMiddleware struct {
        http.Handler
    }
    
    func (cm CORSMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
        cm.Handler.ServeHTTP(w, r)
    }
    

    Then, you can use it like that:

    var h http.Handler = CORSMiddleware{cont}
    r.Handle("/accounts", h)
    r.Handle("/accounts/{id}", h)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥30 python代码,帮调试,帮帮忙吧