如何在我的谷歌脚本中允许 CORS 请求?

Joo*_*aal 5 cors google-apps-script

我想将我的联系表格发布到我的 google 脚本,该脚本将向我发送电子邮件。我使用以下代码:

var TO_ADDRESS = "example@gmail.com"; // where to send form data

function doPost(e) {

  var callback = e.parameter.callback;

  try {
    Logger.log(e); // the Google Script version of console.log
    MailApp.sendEmail(TO_ADDRESS, "Contact Form Submitted",
                      JSON.stringify(e.parameters));
    // return json success results
    return ContentService
          .createTextOutput(callback+
          JSON.stringify({"result":"success",
                          "data": JSON.stringify(e.parameters) }))
          .setMimeType(ContentService.MimeType.JSON);
  } catch(error) { // if error return this
    Logger.log(error);
    return ContentService
          .createTextOutput(callback+JSON.stringify({"result":"error", 
          "error": e}))
          .setMimeType(ContentService.MimeType.JSON);
  }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试发布到 google 脚本 url 时,出现以下错误:

CORS 政策已阻止在 ' https://script.google.com/macros/s/~~myscriptid~~/exec ' 从源 ' http://localhost:4200 '访问 XMLHttpRequest :对预检请求的响应没有't pass access control check: 请求的资源上不存在'Access-Control-Allow-Origin'标头。

我不知道如何将 CORS 过滤器添加到我的谷歌脚本中。

我知道脚本正在运行,我已经用这个插件对其进行了测试:

https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi

Har*_*Das 14

经过大量的努力,唯一对我有用的解决方案:

在 Google Apps 脚本中

function doPost(e) {
  return ContentService.createTextOutput(JSON.stringify({status: "success", "data": "my-data"})).setMimeType(ContentService.MimeType.JSON);
}
Run Code Online (Sandbox Code Playgroud)

在 JavaScript 中

fetch(URL, {
      redirect: "follow",
      method: "POST",
      body: JSON.stringify(DATA),
      headers: {
        "Content-Type": "text/plain;charset=utf-8",
      },
    })
Run Code Online (Sandbox Code Playgroud)

redirect: "follow"注意非常重要的属性;


JRi*_*dsz 5

快速回答

\n

您(前端开发人员)无法修复远程服务器的 cors 错误。只有远程服务器(谷歌应用程序脚本服务器)的所有者才能执行此操作。

\n

解决方法 1 (GET)

\n

在应用程序脚本中仅使用 GET 方法。Get 方法不会抛出 CORS 错误,无论您从哪里使用它:csr、spa、前端、react、Angular、vue、jquery、纯 javascript 等

\n

解决方法 2(后端)

\n

如果您位于后端服务器(java、php、c#、node、ruby、curl 等)而不是前端(浏览器、react、Angular、vue),您可以使用 google apps 脚本上发布的任何方法。

\n

当消费在后端层时,CORS 不受影响

\n

因此,如果仅使用 get 端点不适合您,您可以使用另一种服务器语言(java、nodejs、php 等)来使用 Post google 应用程序脚本,并将该信息返回到您的网络

\n

解释

\n

让我们想象一下这个脚本有 02 个方法在 google 应用程序脚本中部署为 web

\n
function doGet(e) {\n    var response = {\n      "code": 200,\n      "message": "I\'m the get"\n    };\n    return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);\n}\n\nfunction doPost(e) {\n    var response = {\n      "code": 200,\n      "message": "I\'m the post"\n    };\n    return ContentService.createTextOutput(JSON.stringify(response)).setMimeType(ContentService.MimeType.JSON);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

谷歌应用程序脚本部署

\n

部署后的 url 如下:

\n

https://script.google.com/a/utec.edu.pe/macros/s/AKfy\\*\\*\\*\\*\\*\\*eo/exec

\n

在后台

\n

您可以使用任何语言的 POST 和 GET 方法而不会出现任何问题:java、nodejs、python、php、c#、go 等和/或任何 http 客户端(如 postman、insomnia、soapui、curl 等)

\n

在此输入图像描述

\n

在前端(浏览器中的js)

\n

我无法使用POST方法。我尝试使用 jsonp 和其他疯狂的尝试,错误是相同的:

\n
Cross-Origin Request Blocked: The Same Origin Policy disallows \nreading the remote resource at         \nhttps://script.google.com/a/utec.edu.pe/macros/s/AKfy***A4B***eo/exec?foo=bar \n(Reason: CORS header \xe2\x80\x98Access-Control-Allow-Origin\xe2\x80\x99 missing).\n
Run Code Online (Sandbox Code Playgroud)\n

因此,出于任何原因,Google 服务器不允许我们从 javascript 端使用 POST 操作 (2021)

\n

在前端: GET 方法

\n

谷歌应用程序脚本作为获取方法

\n

只有GET方法对我有用。我假设服务器层的 google 配置仅对 GET 方法有一些 CORS 权限。

\n

以下方法对我有用,从简单的 js 到高级框架,如 React、Vue 或 Angular:

\n

\n
const axios = require(\'axios\');\naxios.get(\'https://script.google.com/a/acme.org/macros/s/AKfy***A4B***eo/exec\').then(resp => {\n    console.log(resp.data);\n});\n
Run Code Online (Sandbox Code Playgroud)\n

$.getJSON

\n
$.getJSON(\'https://script.google.com/a/acme.org/macros/s/AKfy***A4B***eo/exec?foo=bar\', function(result) {\n  console.log(result);\n});\n
Run Code Online (Sandbox Code Playgroud)\n

XMLHttp请求

\n
var xmlhttp = new XMLHttpRequest();\nvar theUrl = "https://script.google.com/a/acme.org/macros/s/AKfy***A4B***eo/exec?foo=bar";\nxmlhttp.open("GET", theUrl);\nxmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");\nxmlhttp.send();\n
Run Code Online (Sandbox Code Playgroud)\n

CORS:跨域资源共享

\n

很多开发者不明白什么是CORS。这并不容易理解。通常开发人员会在服务器层修复错误,并且不会投入时间(或者不让他)来理解 CORS 是什么:

\n\n

如果你没有时间,请检查我的定义,极端总结近乎错误:

\n
\n

CORS 是受信任浏览器提供的一种保护,以避免 web acme.com可以在后台(ajax/js)加载来自另一个域(如hacker-api.com/foo/bar)的 http 资源

\n
\n

但是,如果acme.comhacker-api.com/foo/bar是由您开发的和/或hacker-api.com/foo/bar旨在供世界上任何网络使用,您可以在服务器层修复它

\n

如何修复 CORS 错误?

\n

如果服务器属于我们,则非常常见且易于通过服务器中的几行进行控制,但由于我们无法控制服务器(google),因此我们无法在这一层执行任何操作。

\n

这里有一些 CORS 配置示例,允许从属于您的后端服务器进行 Web 消费:

\n

java样本:

\n
Cross-Origin Request Blocked: The Same Origin Policy disallows \nreading the remote resource at         \nhttps://script.google.com/a/utec.edu.pe/macros/s/AKfy***A4B***eo/exec?foo=bar \n(Reason: CORS header \xe2\x80\x98Access-Control-Allow-Origin\xe2\x80\x99 missing).\n
Run Code Online (Sandbox Code Playgroud)\n

节点示例:

\n
//only http://localhost:8080 could consume my api\nvar corsOptions = {\n    origin: \'http://localhost:8080\',\n    optionsSuccessStatus: 200 // For legacy browser support\n}\napp.use(cors(corsOptions));\n\n//any web could consume my api\norigin : "*"\n
Run Code Online (Sandbox Code Playgroud)\n

  • 您介意解释一下您做了什么不同的事情吗?我认为与一般的帖子请求没有什么区别,这是行不通的。 (3认同)

Sam*_*Sam 5

迟到的回答,但完全有效......

要将数据从 appscripts 传递到另一个网站,只需在 appscripts 端使用 mime 类型 JAVASCRIPT,如下所示:

doGet(e){   
 return ContentService
  .createTextOutput(e.parameter.callback + "(" + JSON.stringify(YOUR OBJECT DATA HERE)+ ")")
  .setMimeType(ContentService.MimeType.JAVASCRIPT);
}
Run Code Online (Sandbox Code Playgroud)

并在前端访问它:

<script>
var url = "https://script.google.com/macros/s/AKfy*****ACeR/exec?callback=loadData";
// Make an AJAX call to Google Script
jQuery.ajax({
crossDomain: true,
url: url,
method: "GET",
dataType: "jsonp"
});

 // log the returned data
  function loadData(e) {
  console.log(e);
  }
</script>
Run Code Online (Sandbox Code Playgroud)

这没有任何 CROB/CROS 的麻烦

  • 在处理 POST 请求和 `doPost` 函数时,这对我不起作用。 (2认同)

sky*_*yer 0

据我了解,您有要在自定义域上运行的应用程序。它应该访问谷歌云上的脚本。

坏消息:没有办法跳过应用程序端的 CORS 检查(除非请求很简单,我相信这不是您的情况)。

Access-Control-Allow-Origin您应该在Google Cloud 端指定:

Cloud Storage 仅允许您在存储桶级别设置 CORS 配置。您可以使用 gsutil 命令行工具、XML API 或 JSON API 设置存储桶的 CORS 配置。有关在存储桶上设置 CORS 配置的更多信息,请参阅配置跨源资源共享 (CORS)。有关 CORS 配置元素的更多信息,请参阅设置存储桶 CORS。

您可以使用以下任一 XML API 请求网址从 Cloud Storage 获取包含 CORS 标头的响应:

storage.googleapis.com/[BUCKET_NAME]

[BUCKET_NAME].storage.googleapis.com

如果这因任何原因没有帮助,您将需要让自己的服务器作为代理工作:

您的客户端应用程序 <-> 返回的后端Access-Control-Allow-Origin<-> 谷歌云