0

I am getting an error due to CORS policy. It seems a common issue. I have read other questions and tried some of their solutions, but it still does not work.

My app does the following: 1- GET a list of values from a google sheet and show them in a drop down list in a web app (still using script.google.com) 2- POST the value that the user select in the drop down list from the web app to the sheet.

1 (GET) was working fine with no issues. When I added 2 (POST), it gave me the CORS error for the POST call. The GET seems fine.

Here is the code for POST:

function doPost(e) {
  var value = JSON.parse(e.postData.contents).value;
  var ss = SpreadsheetApp.openById('1Zbvy1x_DsBlcwK4FdjoY4m0MFvS_tYZlGtKvD36fDyk');
  var sh = ss.getSheetByName('Dashboard');
  sh.getRange(92, 2).setValue(value);
  return ContentService.createTextOutput(JSON.stringify({message: "ok"})).setMimeType(ContentService.MimeType.JSON);
}

with HTML file:

<script>
function listQ() {
    const index = this.selectedIndex;
    if (index > 0) {
      const e = document.getElementById("sel1");
      const value = e.options[index].value;
      const url = "https://script.google.com/a/google.com/macros/s/AKfycbxHX7cthji076OrqfY9ZpGa7jNDxKHUMf_ib7Ekmoo0Ir5DQF1Y/exec";  
      fetch(url, {
        method: "POST",
        body: JSON.stringify({index: index, value: value}),
      })
      .then(function (response) {
        return response.json();
      })
      .then(function (data) {
        console.log(data);
      })
    }
  }
document.getElementById("sel1").addEventListener("change",listQ);
</script>

The GET part is fine, so no need to add the code here.

I have tried to change POST with PUT as suggested here: Change Google Sheet data based on user selection in Google Site (Web App) but it gave the same error.

I have also read this link, but mine is a POST request, not GET and I am not sure how to apply it to my case: CORS authorization on google sheets API requests

FYI The "origin" in the CORS error message is ...googleusercontent.com

UPDATE: I have also tried this: Google Apps Script cross-domain requests stopped working

I think I should implement that solution, but when I tried to add those mods in my code and it did not work. Probably I am adding the mods incorrectly since I am not 100% sure what I am doing. I get the error that the call back function is not defined. Here is what I did:

function doPost(e) {
  var callback = e.parameter.callback;
  var value = JSON.parse(e.postData.contents).value;
  var ss = SpreadsheetApp.openById('1ROvDcIQ8JCGvvLvCvTKIqSor530Uj9ZJv-n6hQ761XA');
  var sh = ss.getSheetByName('Dashboard');
  sh.getRange(92, 2).setValue(value);
  return ContentService.createTextOutput(callback+'('+JSON.stringify({message: "ok"})+')').setMimeType(ContentService.MimeType.JSON);
}

and in HTML side, I just modified the URL:

const url = "https://script.google.com/a/google.com/macros/s/AKfycbxHX7cthji076OrqfY9ZpGa7jNDxKHUMf_ib7Ekmoo0Ir5DQF1Y/exec?offset="+offset+"&baseDate="+baseDate+"&callback=?";
Marios
  • 26,333
  • 8
  • 32
  • 52
Filippo
  • 320
  • 2
  • 5
  • 22
  • Why not just use `google.script.run`? – TheMaster May 11 '20 at 17:50
  • could you please elaborate more? I am very new to google app script and javascript. – Filippo May 11 '20 at 17:55
  • See [here](https://developers.google.com/apps-script/guides/html/communication) – TheMaster May 11 '20 at 18:52
  • Unfortunately, I cannot replicate your situation. In order to correctly replicate and understand about your situation, can you provide the detail flow for replicating your issue? And I cannot understand about `I have tried to change POST with PUT as suggested here:`. Can you explain about the detail of it? – Tanaike May 11 '20 at 23:12

1 Answers1

2

In Apps Script Web Apps, in order to access server-side functions from your current project, you don't need to make a GET or POST request to the Web App URL. You just need to use google.script.run.

In your exact case, you could do the following:

function listQ() {
  const index = this.selectedIndex;
  if (index > 0) {
    const e = document.getElementById("sel1");
    const value = e.options[index].value;
    const body = { index: index, value: value };
    google.script.run.withSuccessHandler(yourCallback).yourServerSideFunc(body);
  }
}

function yourCallBack(response) {
  // Whatever you want to do with the data retrieved from server-side
}

In the code above, the client-side function calls a server side function called yourServerSideFunc via google.script.run. If the server-side function returns successfully, a callback function is called (function yourCallback), whose purpose is to handle the data returned from the server (a callback is needed since, on its own, the function called by google.script.run returns void). This callback function receives the content returned by the server-side function as an argument.

And in the server-side, no need to use doPost, since you would not be making a POST request:

function yourServerSideFunc(body) {
  var value = body["value"];
  var ss = SpreadsheetApp.openById('1Zbvy1x_DsBlcwK4FdjoY4m0MFvS_tYZlGtKvD36fDyk');
  var sh = ss.getSheetByName('Dashboard');
  sh.getRange(92, 2).setValue(value);
  return ContentService.createTextOutput(JSON.stringify({message: "ok"})).setMimeType(ContentService.MimeType.JSON);  
}

Reference:

Iamblichus
  • 18,540
  • 2
  • 11
  • 27
  • Thank you so much for your answer! I am sorry about my lack of understanding, I am new to this. You explained that the callback function returns void, but it calls the yourServerSideFunc(body)? which should already set the values in the sheet? Basically what I want to do with the data retrieved from the drop down list is specified in the yourServerSideFunc(body) so not sure what to do with the yourCallBack(response). FYI there is a typo in your answer (yourCallback vs yourCallBack) and I am getting an error: yourServerSideFunc is not defined at yourCallBack. – Filippo May 12 '20 at 16:23
  • Actually it works! I was getting that error, but was still setting the right value in the sheet. Now I am leaving the yourCallBack(response) blank and it dies not give any error message. It works fine! – Filippo May 12 '20 at 16:33