CORS 块:WebApp POST 到 Sheet

CORS block: WebApp POST to Sheet

由于 CORS 政策,我遇到了错误。这似乎是一个普遍的问题。我已经阅读了其他问题并尝试了他们的一些解决方案,但仍然不起作用。

我的应用执行以下操作: 1- 从 google sheet 获取值列表并将它们显示在网络应用程序的下拉列表中(仍在使用 script.google.com) 2- POST 用户 select 从 web 应用到 sheet.

下拉列表中的值

1 (GET) 工作正常,没有任何问题。当我添加 2 (POST) 时,它给了我 POST 调用的 CORS 错误。 GET 看起来不错。

这是 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);
}

与 HTML 文件:

<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>

GET部分就可以了,这里就不用加代码了。

我尝试按照此处的建议用 PUT 更改 POST: 但它给出了同样的错误。

我也读过这个 link,但我的是 POST 请求,不是 GET,我不确定如何将它应用到我的案例中:CORS authorization on google sheets API requests

仅供参考 CORS 错误消息中的 "origin" 是 ...googleusercontent.com

更新: 我也试过这个:

我认为我应该实施该解决方案,但是当我尝试在我的代码中添加这些模组时,它并没有奏效。可能我添加的模组不正确,因为我不是 100% 确定我在做什么。我收到未定义回调函数的错误。这是我所做的:

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);
}

在HTML这边,我刚刚修改了URL:

const url = "https://script.google.com/a/google.com/macros/s/AKfycbxHX7cthji076OrqfY9ZpGa7jNDxKHUMf_ib7Ekmoo0Ir5DQF1Y/exec?offset="+offset+"&baseDate="+baseDate+"&callback=?";

在 Apps Script Web Apps 中,为了从当前项目访问服务器端函数,您不需要向 Web App GETPOST 请求41=]。你只需要使用 google.script.run.

根据您的具体情况,您可以执行以下操作:

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
}

在上面的代码中,客户端函数通过 google.script.run 调用名为 yourServerSideFunc 的服务器端函数。如果服务器端函数 returns 成功,将调用回调函数(函数 yourCallback),其目的是处理从服务器返回的数据(需要回调,因为就其本身而言, google.script.run returns void 调用的函数)。此回调函数接收服务器端函数返回的内容作为参数。

并且在服务器端,无需使用 doPost,因为您不会发出 POST 请求:

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);  
}

参考: