Cross-domain 请求因响应中不存在 `Access-Control-Allow-Origin` header 而停止工作
Cross-domain requests stopped working due to no `Access-Control-Allow-Origin` header present in the response
我有一个使用 Google Apps 脚本创建的错误报告信标,它以我本人的身份发布到 运行 并且“任何人,甚至是匿名的”都可以访问,should 表示允许 X-domain 向 GAS 请求。
但是,我的浏览器现在指示在代码发布到信标后没有 Access-Control-Allow-Origin
header 响应。
我是不是漏掉了什么?就在两个月前,这曾经起作用。只要 GAS 是为 public 访问发布的,那么它 就是 设置 Access-Control-Allow-Origin
header.
在 Google Apps 脚本中:
Code.gs
function doPost(data){
if(data){
//Do Something
}
return ContentService.createTextOutput("{status:'okay'}", ContentService.MimeType.JSON);
}
客户端:
script.js
$.post(beacon_url, data, null, "json");
在调用内容服务脚本时,我总是发送一个 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);
}
只是为了让像我这样只对 POST 请求感兴趣的人更简单:
function doPost(e){
//do stuff ...
var MyResponse = "It Works!";
return ContentService.createTextOutput(MyResponse).setMimeType(ContentService.MimeType.JAVASCRIPT);
}
我在同样的问题上浪费了几个小时。解决方案很简单。
当您将脚本部署为 webapp 时,您会得到两个 URL:/dev
一个和 /exec
一个。您应该使用 /exec
一个来发出跨域 POST 请求。 /dev
始终是私有的:它需要被授权并且不设置 *Allow-Origin header。
PS.: /exec
似乎被冻结了——它不会反映任何代码更改,直到您使用新版本字符串手动部署它(部署对话框中的下拉列表) .要使用 /dev
URL 调试最新版本的脚本,只需安装替代浏览器并禁用它的 web-security 功能(--disable-web-security 在 GoogleChrome 中)。
我偶然发现了同样的问题:
- 当 运行 本地主机
上的网页时,从浏览器调用 /exec
-url 正常
- 从 https 域调用时抛出跨域错误
我试图避免将我的 POST JSON-clientcode 重构为 JSONP(我持怀疑态度,因为以前总是有效)。
可能的修复 #1
幸运的是,在之后我做了一个非 CORS 请求(fetch()
在浏览器中从 https 域,使用 mode: no-cors
),通常CORS 请求再次正常工作。
最后的想法
最后一个解释可能是:每个新的 appscript-deployment 都需要一些 time/usage 才能在服务器级别实际稳定下来。
我的情况不同,我以一种非常奇怪的方式面对 CORS 错误。
我的代码运行正常,没有 CORS 错误,直到我添加了一个常量:
const MY_CONST = "...";
似乎 Google Apps Script (GAS) 不允许 'const' 关键字,GAS 是基于 ES3 或 ES5 之前的类似东西。 'const' 上的错误重定向到没有 CORS 的错误页面 URL。
参考:
当我尝试将应用程序脚本应用程序与另一个 Vue 应用程序集成时,我遇到了类似的 CORS 策略错误问题。
请注意以下配置:
- 每个部署的项目版本应该是 NEW。
- 以 我 的身份执行应用程序,以防您想要授予所有人访问权限。
- 谁有权访问该应用任何人,匿名。
希望这对你有用。
如果这对所有像我这样的人有帮助:
我有一个 .js 文件,其中包含我所有的实用函数,包括调用 GAS 的函数。我在测试更新时总是忘记清除缓存,所以我经常会遇到这种错误,因为缓存代码使用的是 /dev link 而不是 /exec。
在您的调用应用程序中,只需将内容类型设置为 text/plain,您就可以将 GAS 返回的 JSON 解析为有效的 json 对象。
这是我的 google 脚本 doPost 函数中的 JSON 对象
var result = {
status: 200,
error: 'None',
rowID: rowID
};
ws.appendRow(rowContents);
return ContentService.createTextOutput(JSON.stringify(result))
.setMimeType(ContentService.MimeType.JSON);
在这里我从节点 js
调用我的应用程序脚本 API
const requestOptions = {
method: 'POST',
headers: {'Content-Type': 'text/plain'},
body: JSON.stringify({param1: value, param2:value})
};
const response = await fetch(server_URL, requestOptions);
const data = await response.json();
console.log(data);
console.log(data.status);
以下解决方案适合我
在 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"
,这是非常非常重要的。没有它,它对我不起作用。
我有一个使用 Google Apps 脚本创建的错误报告信标,它以我本人的身份发布到 运行 并且“任何人,甚至是匿名的”都可以访问,should 表示允许 X-domain 向 GAS 请求。
但是,我的浏览器现在指示在代码发布到信标后没有 Access-Control-Allow-Origin
header 响应。
我是不是漏掉了什么?就在两个月前,这曾经起作用。只要 GAS 是为 public 访问发布的,那么它 就是 设置 Access-Control-Allow-Origin
header.
在 Google Apps 脚本中:
Code.gsfunction doPost(data){
if(data){
//Do Something
}
return ContentService.createTextOutput("{status:'okay'}", ContentService.MimeType.JSON);
}
客户端:
script.js$.post(beacon_url, data, null, "json");
在调用内容服务脚本时,我总是发送一个 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);
}
只是为了让像我这样只对 POST 请求感兴趣的人更简单:
function doPost(e){
//do stuff ...
var MyResponse = "It Works!";
return ContentService.createTextOutput(MyResponse).setMimeType(ContentService.MimeType.JAVASCRIPT);
}
我在同样的问题上浪费了几个小时。解决方案很简单。
当您将脚本部署为 webapp 时,您会得到两个 URL:/dev
一个和 /exec
一个。您应该使用 /exec
一个来发出跨域 POST 请求。 /dev
始终是私有的:它需要被授权并且不设置 *Allow-Origin header。
PS.: /exec
似乎被冻结了——它不会反映任何代码更改,直到您使用新版本字符串手动部署它(部署对话框中的下拉列表) .要使用 /dev
URL 调试最新版本的脚本,只需安装替代浏览器并禁用它的 web-security 功能(--disable-web-security 在 GoogleChrome 中)。
我偶然发现了同样的问题:
- 当 运行 本地主机 上的网页时,从浏览器调用
- 从 https 域调用时抛出跨域错误
/exec
-url 正常
我试图避免将我的 POST JSON-clientcode 重构为 JSONP(我持怀疑态度,因为以前总是有效)。
可能的修复 #1
幸运的是,在之后我做了一个非 CORS 请求(fetch()
在浏览器中从 https 域,使用 mode: no-cors
),通常CORS 请求再次正常工作。
最后的想法
最后一个解释可能是:每个新的 appscript-deployment 都需要一些 time/usage 才能在服务器级别实际稳定下来。
我的情况不同,我以一种非常奇怪的方式面对 CORS 错误。
我的代码运行正常,没有 CORS 错误,直到我添加了一个常量:
const MY_CONST = "...";
似乎 Google Apps Script (GAS) 不允许 'const' 关键字,GAS 是基于 ES3 或 ES5 之前的类似东西。 'const' 上的错误重定向到没有 CORS 的错误页面 URL。
参考:
当我尝试将应用程序脚本应用程序与另一个 Vue 应用程序集成时,我遇到了类似的 CORS 策略错误问题。
请注意以下配置:
- 每个部署的项目版本应该是 NEW。
- 以 我 的身份执行应用程序,以防您想要授予所有人访问权限。
- 谁有权访问该应用任何人,匿名。
希望这对你有用。
如果这对所有像我这样的人有帮助:
我有一个 .js 文件,其中包含我所有的实用函数,包括调用 GAS 的函数。我在测试更新时总是忘记清除缓存,所以我经常会遇到这种错误,因为缓存代码使用的是 /dev link 而不是 /exec。
在您的调用应用程序中,只需将内容类型设置为 text/plain,您就可以将 GAS 返回的 JSON 解析为有效的 json 对象。
这是我的 google 脚本 doPost 函数中的 JSON 对象
var result = {
status: 200,
error: 'None',
rowID: rowID
};
ws.appendRow(rowContents);
return ContentService.createTextOutput(JSON.stringify(result))
.setMimeType(ContentService.MimeType.JSON);
在这里我从节点 js
调用我的应用程序脚本 API const requestOptions = {
method: 'POST',
headers: {'Content-Type': 'text/plain'},
body: JSON.stringify({param1: value, param2:value})
};
const response = await fetch(server_URL, requestOptions);
const data = await response.json();
console.log(data);
console.log(data.status);
以下解决方案适合我
在 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"
,这是非常非常重要的。没有它,它对我不起作用。