javascript - Google App Script Web App GET 和 POST 请求被 CORS 策略阻止
问题描述
我创建了一个将用户名和电子邮件添加到电子表格的 Google Web 脚本应用程序。当直接在浏览器中访问网页时,这可以正常工作,但来自网站的 GET 和 POST 请求都会返回错误“访问以在 ' https://script.google.com/macros/s/AKfycbxkG5hM6MMswwHdzWSJKwutMYsOZRT3zjC7jFti0sDvJ47bWB4BTsHPhvbyEVGSsSc5/exec处获取” CORS 策略已阻止 from origin '':请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。”
我不一定需要来自 POST 请求的响应,但使用“no-cors”实际上不会更新电子表格(我进行了测试以确保它在网站之外工作)
我使用了 XMLHttpRequest 和 fetch 方法,同时使用了 GET 和 POST 请求,并且更改了各种设置以尝试使其正常工作,但到目前为止还没有运气。
我尝试修改 Google Apps 脚本项目中的设置(设置为像我一样执行,任何人甚至可以匿名访问)和清单(这里不多,文档参考)。
我查看了这些堆栈溢出帖子以试图提供帮助,但他们的解决方案对我不起作用(任何不完全适用于我的情况)
这是我的 fetch 方法(最近的尝试)
fetch("https://script.google.com/macros/s/AKfycbxkG5hM6MMswwHdzWSJKwutMYsOZRT3zjC7jFti0sDvJ47bWB4BTsHPhvbyEVGSsSc5/exec", {
method: 'POST',
data: data,
mode: 'cors',
credentials: 'include', // include, *same-origin, omit
redirect: 'follow',
headers: {
'Content-Type': 'text/plain;charset=utf-8',
}
}).then(response => {
console.log("success:", response);
});
现在服务器应该返回一个显示“成功”的字符串,但我得到了我之前提到的错误。
编辑 我忘记在 Google App Script 中包含 doGet 和 doPost 方法:
var emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
function doPost (e){
if(!e) return ContentService.createTextOutput("No e");
if(!e.parameters) return ContentService.createTextOutput("No params");
if(!e.parameters.email) return ContentService.createTextOutput("No email");
if(!e.parameters.name) return ContentService.createTextOutput("No name");
if(!emailRegex.test(e.parameters.email)) return ContentService.createTextOutput("Wrong email format"); // if the email is not in proper format, return
return addToDoc(e.parameters);
}
function doGet (e){
if(!e) return ContentService.createTextOutput("No e");
if(!e.parameters) return ContentService.createTextOutput("No params");
if(!e.parameters.email) return ContentService.createTextOutput("No email");
if(!e.parameters.name) return ContentService.createTextOutput("No name");
if(!emailRegex.test(e.parameters.email)) return ContentService.createTextOutput("Wrong email format"); // if the email is not in proper format, return
return addToDoc(e.parameters);
}
function addToDoc (params){
var email = params.email;
var name = params.name;
var sheet = SpreadsheetApp.openById("1X0sUNSFcv-phGbGy7jeo9K5WLEX5cxyh_1_X6kSPjPs").getSheets()[0];
var dataRange = sheet.getDataRange();
var values = dataRange.getValues();
// If we already have the email in the system, return
for(var x = 0; x < values.length; x++){
for(var y = 0; y < values[x].length; y++){
if(values[x][y].indexOf(email) > -1) return ContentService.createTextOutput("Already have email");
}
}
// Gets current row index and updates
var scriptProps = PropertiesService.getScriptProperties();
var nextDataIndex = parseInt(scriptProps.getProperty("NEXT_DATA_INDEX"));
scriptProps.setProperty("NEXT_DATA_INDEX", ""+(nextDataIndex+1));
var insertRange = sheet.getRange(nextDataIndex, 1, 1, 2);
insertRange.setValues([[name, email]]);
return ContentService.createTextOutput("Success");
}
解决方案
所以事实证明我的 doPost 请求失败(doGet 正在工作),因为我正在使用e.parameters
而不是e.postData
. 当我收到错误消息时,我认为这是我的网站的问题,而不是网络应用程序的问题。
谢谢田池!我会一直努力修复网站
解决方案
尽管从您的问题中我不确定您的网络应用程序的 Google Apps 脚本,但此修改如何?
修改点:
我认为您的 Web 应用程序可能不会返回任何值。您可以放入和
return ContentService.createTextOutput()
的功能。这样,在 Google Apps 脚本中,状态 200 被返回。doPost()
doGet()
function doPost(e) { // or doGet(e) // do something return ContentService.createTextOutput(); // Please add this. }
您可以按如下方式修改客户端脚本:
fetch("https://script.google.com/macros/s/AKfycbxkG5hM6MMswwHdzWSJKwutMYsOZRT3zjC7jFti0sDvJ47bWB4BTsHPhvbyEVGSsSc5/exec", { method: 'POST', body: data, headers: { 'Content-Type': 'text/plain;charset=utf-8', } }).then(response => { console.log("success:", response); }).catch(err => { console.log("Error:" + err); });
笔记:
- 当您修改 Web Apps 的 Google Apps 脚本时,请将 Web Apps 部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。请注意这一点。
参考:
如果我误解了您的问题并且这不是您想要的结果,我深表歉意。
推荐阅读
- php - 用于查询构建器的 Sql - Symfony
- c# - 在 Entity Framework Core 中实例化 GUID 是不好的做法吗?
- ibm-cloud - 有没有办法在一次 api 调用中获得整合的 IBM Cloud 计费
- python - 在 Jupyter Windows 上使用 pool 并行读取多个文件需要很长时间:
- django - 通过 Django admin 删除对象时是否可以禁用相关对象的生成?
- android - Android Gradle 文件从库中的应用程序的 .json 文件中获取值
- angular - 在Angular 7中无法获得选择的价值
- java - OpenCL 和 Java - 奇怪的性能结果
- scala - 无法使用 Spark 访问 Hive 仓库目录
- typescript - 带有 TypeScript 的 ES5 生成器的 Polyfill