Google App Script Web App GET 和 POST 请求被 CORS 策略阻止

Posted

技术标签:

【中文标题】Google App Script Web App GET 和 POST 请求被 CORS 策略阻止【英文标题】:Google App Script Web App GET and POST request blocked by CORS policy 【发布时间】:2019-10-23 10:04:06 【问题描述】:

我创建了一个 Google Web 脚本应用程序,可将用户名和电子邮件添加到电子表格中。当直接在浏览器中访问网页时,这可以正常工作,但是来自网站的 GET 和 POST 请求都返回错误“访问从原点'https://script.google.com/macros/s/AKfycbxkG5hM6MMswwHdzWSJKwutMYsOZRT3zjC7jFti0sDvJ47bWB4BTsHPhvbyEVGSsSc5/exec'获取''已被 CORS 策略阻止:没有'访问-Control-Allow-Origin' 标头存在于请求的资源上。如果不透明的响应满足您的需求,请将请求的模式设置为 'no-cors' 以获取禁用 CORS 的资源。"

我不一定需要来自 POST 请求的响应,但使用“no-cors”实际上不会更新电子表格(我进行了测试以确保它在网站之外工作)

我同时使用了 XMLHttpRequest 和 fetch 方法,同时使用了 GET 和 POST 请求,并更改了各种设置以尝试使其正常工作,但到目前为止还没有成功。

我尝试修改 Google Apps 脚本项目(设置为以我身份执行,任何人都可以匿名访问)和清单(这里不多,documentation reference)中的设置。

我查看了这些堆栈溢出帖子以试图提供帮助,但他们的解决方案对我不起作用(任何不完全适用于我的情况)

App Script sends 405 response when trying to send a POST request

Google Apps Script cross-domain requests stopped working

这是我的 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 应用脚本中包含 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。当我收到错误消息时,我认为这是我的网站的问题,而不是网络应用程序的问题。

谢谢田池!我会一直努力修复网站

【问题讨论】:

【参考方案1】:

虽然从您的问题中我不确定您的 Google Apps 网络应用程序脚本,但是这个修改怎么样?

修改点:

    我认为您的 Web 应用程序可能不会返回任何值。您可以将return ContentService.createTextOutput() 放在doPost()doGet() 的函数中。这样,在 Google Apps 脚本中,状态 200 被返回。

    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 应用程序中。请注意这一点。

参考资料:

createTextOutput() Using Fetch Taking advantage of Web Apps with Google Apps Script

如果我误解了您的问题并且这不是您想要的结果,我深表歉意。

【讨论】:

我遇到了同样的问题,将内容类型更改为 text/plain 修复了它。非常感谢您的帮助。 非常感谢!一直在寻找一个小时的答案,'text/plain;charset=utf-8' 就像一个魅力!【参考方案2】:

我必须将访问权限从只有我更改为任何人。

【讨论】:

【参考方案3】:

只有以下对我有用:

在 Google Apps 脚本中

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

javascript

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

【讨论】:

以上是关于Google App Script Web App GET 和 POST 请求被 CORS 策略阻止的主要内容,如果未能解决你的问题,请参考以下文章

Google App Script Web App 上的并发命中数或同时执行数是不是有任何限制

如何向 Google Apps Script Web App 发送有效的 HTTP 请求?

将cURL与PHP文件中的Google Apps Script Web App一起使用时遇到问题

php [appscript api] google app script api

如何从 Google OAuth 2.0 Playground 运行 Google App Script 功能 |调用者没有权限

在Google App Script中使用导入的模块