由于响应中不存在“Access-Control-Allow-Origin”标头,跨域请求停止工作

IT技术 javascript google-apps-script cors cross-domain
2021-03-13 22:36:23

我有一个错误报告信我创建了使用谷歌Apps的脚本,并将其发布到我自己运行,并为想“任何人,甚至是匿名的,”这接近意味着X-域请求GAS是允许的。

但是,Access-Control-Allow-Origin在代码发布到信标后,我的浏览器现在显示响应中没有标头。

我在这里错过了什么吗?这曾经在两个月前有效。只要气体公布,供公众查阅,那么它设置Access-Control-Allow-Origin标题。

在 Google Apps 脚本中:

代码.gs
function doPost(data){
  if(data){
        //Do Something
  }
  return ContentService.createTextOutput("{status:'okay'}", ContentService.MimeType.JSON);
}

客户端:

脚本.js
$.post(beacon_url, data, null, "json");
6个回答

在调用 contentservice 脚本时,我总是为 JSONP 发送回调。由于 GAS 不支持 CORS,这是确保您的应用程序在 x 域问题到来时不会中断的唯一可靠方法。

在 jQuery 中进行调用只需添加“&callback=?”。它会弄清楚其他一切。

 var url = "https://script.google.com/macros/s/{YourProjectId}/exec?offset="+offset+"&baseDate="+baseDate+"&callback=?";
 $.getJSON( url,function( returnValue ){...});

在服务器端

function doGet(e){
 var callback = e.parameter.callback;
 //do stuff ...
 return ContentService.createTextOutput(callback+'('+ JSON.stringify(returnValue)+')').setMimeType(ContentService.MimeType.JAVASCRIPT);
}
我将此标记为答案,但它有点偏离,因此您可能需要编辑。出于某种原因,在 createTextOutput 中设置内容类型,即使将其设置为 JavaScript 也不能​​解决问题。但是,使用函数 setContentType 并将其设置为 JavaScript 确实有效。另外,在这个用例中,我使用的是 POST,而不是 GET 请求。
2021-04-25 22:36:23
是的,JSONP 不适用于 Post。你描述的一切听起来都是正确的。以“我”的身份运行应用程序,允许访问“匿名”。确保您调用的是已发布的地址,而不是开发者地址。如果所有这些都设置好了,你应该有: Access-Control-Allow-Origin: * 我已经用 hurl.it 测试了一个小脚本。我看到所有正确的标题从那里返回。
2021-04-26 22:36:23
请注意,如果由于某种原因脚本中出现错误,它将返回 text/html MIME 类型而不是 JSON,然后将导致 CORS 错误。所以这也可能是你的问题的原因。
2021-05-20 22:36:23

我已经因为同样的问题失去了几个小时。解决方法很简单。

当您将脚本部署为 webapp 时,您将获得两个 URL:/dev一个和/exec一个。您应该使用/exec一个来进行跨域 POST 请求。/dev一个总是私人的:它需要被授权和没有设置*允许来源头。

PS.:那个/exec似乎被冻结了——它不会反映任何代码更改,直到您使用新版本字符串手动部署它(部署对话框中的下拉列表)。要使用/devURL调试最新版本的脚本,只需安装替代浏览器并禁用其网络安全功能(GoogleChrome 中的--disable-web-security)。

为了将来参考,这篇博文似乎对此进行了详细说明:Google Apps Script Content Service - Cross Domain Puzzle这里还有非常相关的信息:App Script sent 405 response when试图发送 POST 请求看起来, /exec 范围只会在简单请求的情况下按预期传递 CORS
2021-04-23 22:36:23
非常感谢您添加有关如何冻结代码的详细信息。我一直在寻找几个小时,困惑的 b/c 我正在做每件事,但它仍然给我 CO 错误。我很感激他们不会自动版本化它,因此每次更改警报时它都不会生成十亿个版本的代码,但同时在那里包含一个注释会很好,“嘿,如果你用新代码部署它,你需要指定一个新版本。”
2021-05-04 22:36:23
@Novack 你救了我的一天!将请求Content-typeapplication/json默认更改为 AJAXapplication/x-www-form-urlencoded解决了我的预检 405 问题!
2021-05-10 22:36:23

只是为了让像我这样只对 POST 请求感兴趣的人更简单:

function doPost(e){

 //do stuff ...

 var MyResponse = "It Works!";

 return ContentService.createTextOutput(MyResponse).setMimeType(ContentService.MimeType.JAVASCRIPT);

}
感谢您更新其他解决方案,是的,这是很久以前的事了!仍然对一些人有效。
2021-04-28 22:36:23
@jj_ 当您部署 web 应用程序时,它们开始使用 /exec URL。下面我的回答中有更多详细信息。
2021-05-06 22:36:23
这在 2018 年似乎对我不起作用。我仍然收到 CORS 错误。
2021-05-13 22:36:23

我偶然发现了同样的问题:

  • /exec在本地主机上运行网页时,从浏览器调用-urls 很顺利
  • 从 https 域调用时抛出跨域错误

我试图避免将我的 POST JSON-clientcode 重构为 JSONP(我持怀疑态度,因为以前总是有效的)。

可能的修复 #1

幸运的是,我做了一个非 CORS 请求(fetch()在来自 https 域的浏览器中,使用mode: no-cors)之后,通常的 CORS 请求再次正常工作。

最后的想法

最后一个解释可能是:每个新的 appscript-deployment 在其配置实际稳定在服务器级别之前都需要一些时间/使用。

我得试试这个。也许自从我第一次发布这个问题以来的 5 年里发生了很大的变化。
2021-05-15 22:36:23

当我尝试将应用程序脚本应用程序与另一个 Vue 应用程序集成时,我遇到了类似的 CORS 策略错误问题。

请注意以下配置:

  1. 每次部署的项目版本都应该是的。
  2. 如果您想授予所有人的访问权限,请一样执行该应用程序
  3. 谁有权访问该应用程序的任何人,匿名

希望这对你有用。