Search code examples
reactjsgoogle-sheetsgoogle-apps-scriptcors

Vite causing CORS error while sending object data of React app to Google Sheets


I am trying to use Google Sheets for storing my data of my React app. The following is my component code:


    const data = {
      ...userData,
      ...selectedOptions.reduce((acc, option, index) => {
        const alphabetOption = numericToAlphabets[option];
        acc[`question${index + 1}`] = alphabetOption;
        return acc;
      }, {}),
    };

    try {
      await axios.post(googleScriptUrl, data);
    } catch (error) {
      console.log(error);
    }

I am using the following AppScript for my project. I have named the columns in the sequence of my data field. The following is the Google Sheet AppScript

  const sheet = SpreadsheetApp.openByUrl("google-sheet-url").getSheetByName("Sheet1");
  const data = e.parameter;
  sheet.appendRow([
    data.name,
    data.email,
    data.education,
    data.gender,
    data.dateOfBirth,
    ...Object.keys(data).filter(key => key.startsWith("question")).map(key => data[key]),
  ]);

  // Set CORS headers
  const responseHeaders = {
    'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': '*', // Allow requests from any origin (replace with specific origin if needed)
    'Access-Control-Allow-Methods': 'POST',
    'Access-Control-Allow-Headers': 'Content-Type'
  };

  const response = ContentService.createTextOutput("Your message was successfully sent to the Google Sheet database!");
  response.setMimeType('application/json');
  response.setHeaders(responseHeaders);
  return response;
}

The following is the error:


Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at "google-sheet-url" (Reason: CORS request did not succeed). Status code: (null).

Object { stack: "AxiosError@http://localhost:3000/node_modules/.vite/deps/axios.js?v=481c8f0f:377:18\nhandleError@http://localhost:3000/node_modules/.vite/deps/axios.js?v=481c8f0f:1450:14\n", message: "Network Error", name: "AxiosError", code: "ERR_NETWORK", config: {…}, request: XMLHttpRequest }```

How can I debug this error?

Solution

  • I used fetch along with a proxy server instead of using get and post, and now it works fine for me. Here's the code:

        const proxyUrl = "http://localhost:8080/";
    const targetUrl = import.meta.env.VITE_GoogleAppScript;
    console.log(data);
    
    try {
      const params = new URLSearchParams(data);
      const body = params.toString();
    
      const response = await fetch(`${proxyUrl}${targetUrl}`, {
        method: "POST",
        body: body,
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
      });
    

    Here's the Google App Script:

    const sheets = SpreadsheetApp.openByUrl("google-sheet-url");
    const sheet = sheets.getSheetByName("Sheet1");
    
    function doPost(e) {
      const data = e.parameter;
    
      console.log("Received Data:", data);
    
      const name = data.name;
      const email = data.email;
      const education = data.education;
      const gender = data.gender;
      const dateOfBirth = data.dateOfBirth;
      const question1 = data.question1;
      const question2 = data.question2;
      const question3 = data.question3;
      const question4 = data.question4;
      const question5 = data.question5;
      const question6 = data.question6;
      const question7 = data.question7;
      const question8 = data.question8;
      const question9 = data.question9;
      const question10 = data.question10;
    
    
      sheet.appendRow([name, email, education, gender, dateOfBirth, question1, question2, question3, question4, question5, question6, question7, question8, question9, question10]);
    
        const response = ContentService.createTextOutput(JSON.stringify(data));
      response.setMimeType(ContentService.MimeType.JSON);
      response.setStatusCode(200);
      const headers = {
        "Access-Control-Allow-Origin": "http://localhost:3000"
      };
      return response.setResponseHeaders(headers);
    }
    

    And here's the proxyServer code:

    import cors_anywhere from "cors-anywhere";
    
    const host = "localhost";
    const port = 8080;
    
    cors_anywhere
      .createServer({
        originWhitelist: ["http://localhost:3000"],
        requireHeader: ["origin", "x-requested-with"],
        removeHeaders: ["cookie", "cookie2"],
      })
      .listen(port, host, function () {
        console.log(`Running CORS Anywhere on ${host}:${port}`);
      });