CORS block: WebApp POST to Sheet

99封情书 提交于 2020-05-17 06:25:08

问题


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=?";

回答1:


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:

  • HTML Service: Communicate with Server Functions
  • Class google.script.run (Client-side API)


来源:https://stackoverflow.com/questions/61735101/cors-block-webapp-post-to-sheet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!