Home > Back-end >  CORS issue - React/Axios Frontend and Golang Backend
CORS issue - React/Axios Frontend and Golang Backend

Time:03-26

I have a backend REST API service written in Golang. I used axios in the React frontend to POST to the API. Even though I think I have enabled the CORS for both the frontend and backend, the browser still throws this error:

Access to XMLHttpRequest at 'http://localhost:8080/winERC20' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.

Can anyone please suggest what I should do to solve this?

main.go

func main() {
    fmt.Println("Server is serving at http://localhost:8080/")
    // Init the mux router
    router := mux.NewRouter()
    router.HandleFunc("/", helloHandler)
    router.HandleFunc("/matchingABI", api.MatchingContractABI)
    router.HandleFunc("/winERC20", api.WinERC20_controller).Methods("POST", "OPTIONS")
    log.Fatal(http.ListenAndServe(":8080", router))
}

api.go

    func WinERC20_controller(w http.ResponseWriter, r *http.Request) {
        enableCors(&w)

        if r.Method == "OPTIONS" {
            w.WriteHeader(http.StatusOK)
            return
        }
        // Try to decode the request body into the struct. If there is an error,
        // respond to the client with the error message and a 400 status code.
        var p winERC20_RequestBody
        err := json.NewDecoder(r.Body).Decode(&p)
        if err != nil {
            http.Error(w, err.Error(), http.StatusBadRequest)
            return
        }
    
        ...
    
        w.Header().Set("Content-Type", "application/json")
        resp := make(map[string]string)
        resp["message"] = "Success"
        jsonResp, err := json.Marshal(resp)
        if err != nil {
            log.Fatalf("Error happened in JSON marshal. Err: %s", err)
        }
        w.Write(jsonResp)
    }
    
    func enableCors(w *http.ResponseWriter) {
        header := (*w).Header()
        header.Add("Access-Control-Allow-Origin", "*")
        header.Add("Access-Control-Allow-Methods", "DELETE, POST, GET, OPTIONS")
        header.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
    }

frontend.js

grantERC20(){
        // Transfer ERC20 to the player
        let url = 'http://localhost:8080/winERC20'
        let config = {
            headers: {
                "Content-Type": "application/json",
                'Access-Control-Allow-Origin': '*',
            }
        }
        let data = {
            "PublicAddress" : this.props.account,
            "Amount": this.props.score
        }
        axios.post(url, data, config)
        .then(
            (response) => {console.log(response)},
            (error) => {console.log(error);}
        );
    }

componentDidMount () {
        this.grantERC20()
}

CodePudding user response:

Why, in your client-side code, are you adding a header named Access-Control-Allow-Origin to your request? That header is a response header, not a request header. Moreover, CORS preflight is bound to fail because your CORS configuration doesn't allow such a request header:

header.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")

The remedy is simple: just drop that Access-Control-Allow-Origin header from your request.

Besides, instead of implementing CORS "manually" (which is error-prone), you should consider relying on some proven CORS middleware, such as https://github.com/rs/cors.

  • Related