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

Posted

技术标签:

【中文标题】如何在我的谷歌脚本中允许 CORS 请求?【英文标题】:How do i allow a CORS requests in my google script? 【发布时间】:2019-04-25 07:31:32 【问题描述】:

我想将我的联系表格发布到我的 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);
  

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

访问 XMLHttpRequest 在 'https://script.google.com/macros/s/~~myscriptid~~/exec' 来自原点 'http://localhost:4200' 已被 CORS 策略阻止:响应 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。

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

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

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

【问题讨论】:

您的脚本希望在哪里运行?我相信目前您出于开发目的从 localhost 运行它。但是你打算在未来如何使用它? 脚本在谷歌云中运行,我的应用程序在本地主机上运行。这是一项学校作业。 根据错误消息,您在localhost 运行的脚本正在尝试访问谷歌云。但是你说脚本应该在谷歌云上运行。我错过了什么吗? 脚本在谷歌云上运行,并被我的 Angular 应用程序调用。 sou CORS 会影响您的角度应用程序。最终将在哪里运行?根据它是否也可以在云上运行,可能有不同的解决方案, 【参考方案1】:

CORS 错误很可能是由您的 Google Apps 网络应用脚本中的致命错误引起的。在这种情况下,Google 错误处理系统会显示一个不包含 CORS 标头的人类可读的 html 页面。

在我的情况下,我收到以下错误页面:

【讨论】:

【参考方案2】:

在应用脚本中始终使用新部署来部署脚本。

否则它将使用旧脚本,您将收到 CORS 错误

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案3】:

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

在 Google Apps 脚本中

function doPost(e) 
  return ContentService.createTextOutput(JSON.stringify(status: "success", "data": "my-data")).setMimeType(ContentService.MimeType.JSON);

javascript

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

注意很重要的属性redirect: "follow"

【讨论】:

【参考方案4】:

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

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

doGet(e)   
 return ContentService
  .createTextOutput(e.parameter.callback + "(" + JSON.stringify(YOUR OBJECT DATA HERE)+ ")")
  .setMimeType(ContentService.MimeType.JAVASCRIPT);

在前端访问它:

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

这工作没有任何 CROB/CROS 头痛

【讨论】:

在处理 POST 请求和 doPost 函数时,这对我不起作用。【参考方案5】:

经过几个小时的 CORS 研究、jsonp 和其他疯狂尝试,这对我有用,以便使用由以下人员提供的简单 http 端点:

$.post('https://script.google.com/a/acme.org/macros/s/AKfy***A4B***eo/exec?token=myprecioustoken&operation=findAll', null).done(function(response) 
  console.log(response);
);

其余的尝试,给我这个错误:

Cross-Origin Request Blocked: The Same Origin Policy disallows
    reading the remote resource at
    https://script.google.com/a/utec.edu.pe/macros/s/AKfy***A4B***eo/exec?token=myprecioustoken&operation=findAll.
    (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

$.getJSON

$.getJSON('https://script.google.com/a/acme.org/macros/s/AKfy***A4B***eo/exec?token=myprecioustoken&operation=findAll', function(result) 
  console.log(result);
);

XMLHttpRequest

    var xmlhttp = new XMLHttpRequest();
    var theUrl = "https://script.google.com/a/acme.org/macros/s/AKfy***A4B***eo/exec?token=myprecioustoken&operation=findAll";
    xmlhttp.open("POST", theUrl);
    xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    xmlhttp.send();

【讨论】:

您介意解释一下您所做的不同之处吗?我认为与一般的发布请求没有区别,这不起作用。【参考方案6】:

经过几次尝试,我能够通过 Angular 8 的 Web 应用程序表单发送数据。 解决方案很简单,在“HttpClient.post”中,您可以输入第三个参数来建立 HTTP 连接标头,这对于“https://script.google.com”可能不正确,并且会以 CORS 安全失败的 http 连接结束。

只是不要将HTTP连接头作为HttpClient.post的第三个参数添加

const object = 
  title: 'Prices',
  phone: '999999999',
  full_name: 'Jerson Antonio',
  email: 'test@example.com',
  message: 'Hello, .......'
;
return this.http.post(this.API_REST_FORM, JSON.stringify(object));

【讨论】:

【参考方案7】:

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

坏消息:在您的应用程序端无法跳过 CORS 检查(直到 request is simple 我相信这不是您的情况)。

您应该在Google Cloud side 上指定Access-Control-Allow-Origin

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

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

storage.googleapis.com/[BUCKET_NAME]

[BUCKET_NAME].storage.googleapis.com

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

您的客户端应用程序 返回 Access-Control-Allow-Origin 的后端 google cloud

【讨论】:

以上是关于如何在我的谷歌脚本中允许 CORS 请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Google Cloud Endpoints 中允许 CORS?

如何在无服务器中允许 CORS 用于自定义标头?

如何解决 cors 在 vue js 和 laravel 应用程序中允许访问控制

如何在 node.js 中允许 CORS?

如何在 NodeJS 14 中允许 CORS

在 Ruby on Rails 中允许 CORS