reactjsfirebasegoaxiosfly

After switching my app to a new database, I am getting CORS request errors, even though none of my code has changed. Why would this happen?


I had a small app that was running flawlessly for almost two years. It consisted of:

  1. Postgres database hosted on fly.io
  2. API server written in Go, also hosted on fly.io
  3. Front-end client using react and axios, hosted on firebase

A few weeks ago, the database stopped working (I'm not sure why), so I decided to create a new database on Supabase and swap that into my stack. I did this via changing the database URL in the environment secrets, so not a single line of actual code was changed. After the switch, GET and POST requests from the front-end client worked just as before, but now POST and DELETE requests were met with CORS request errors.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://blah.com/api/v1/friends/friend/?friend=test. (Reason: CORS request did not succeed). Status code: (null). ... message: "Network Error", name: "AxiosError", code: "ERR_NETWORK"

I did not change a single line of code, so I have no idea why this would suddenly start happening.

API Server Code

func enableCors(w *http.ResponseWriter) {
    (*w).Header().Set("Access-Control-Allow-Origin", "*")
    (*w).Header().Set("Access-Control-Allow-Headers", "Content-Type")
}

if r.Method == "DELETE" {
        enableCors(&w)
        // check if friend exists
        if friendExists(db, friendParam) {
            query := fmt.Sprintf("DELETE FROM friends WHERE name='%s'", friendParam)

            _, err := db.Query(query)
            if err != nil {
                panic(err.Error())
            }

            w.WriteHeader(http.StatusAccepted)
            w.Write([]byte("202 - Friend deleted: " + friendParam))
        } else {
            w.WriteHeader(http.StatusNotFound)
            w.Write([]byte("404 - Friend not found"))
    }
}

Front-end Client Code

  const onDelete = () => {
    axios({
      method: "delete",
      url:
        "https://blah.com/api/v1/friends/friend/?friend=" +
        friend.FriendName,
      // headers: { "Content-Type": "application/json" },
    })
      .then(function (response) {
        console.log(response);
        navigate("/");
      })
      .catch(function (error) {
        console.log(error);
      });
  };

The first thing I tried was to test the API using curl, and both POST and DELETE requests work as intended. This makes me think the API server is working as intended.

The second thing I tried was to add enableCors(&w) to my API code. That function always existed in my original code, but I tried adding it specifically to the DELETE and POST if statements, but it did not fix the error. My updated code is posted above.

When I changed my fly environment secret, I had to redeploy the API server. I'm wondering if I inadvertently updated Go to 1.23 (I was previously using 1.16, and that's what's stated in my go.mod file.) If Go did get updated, then perhaps I need to update axios (and possibly other things) on my front-end client too?

At this point, I'm not even sure whether the broken component is my API server or the front-end client.


Solution

  • The problem is that I wasn't handling and allowing OPTIONS requests.

    func enableCors(w *http.ResponseWriter) {
        (*w).Header().Set("Access-Control-Allow-Origin", "*")
    
        // the below line was added
        (*w).Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
    
        (*w).Header().Set("Access-Control-Allow-Headers", "Content-Type")
    }
    
    // the below if statement was added
    if r.Method == "OPTIONS" {
        enableCors(&w)
    }
    

    With these changes, everything is now working as it previously did.