【问题标题】:Why can't I get my UrlFetchApp.fetch to use the doGet()?为什么我不能让我的 UrlFetchApp.fetch 使用 doGet()?
【发布时间】:2020-06-20 08:19:00
【问题描述】:

如果我使用两种相同的表单,但当我运行它们时,一种具有 GET 方法,另一种具有 POST 方法,一种使用 doGet,另一种使用 doPost()。但是,当我通过提供来自 Prompt 的输入对 UrlFetch() 命令执行相同操作时,就不会发生这种情况。

html:

顶部表单是 GET,底部表单是 POST。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
  <h3>GET</h3>
    <form action="https://script.google.com/a/cooper/macros/s/AKfycbzlYgw2cw8q7u9qTxM/exec" enctype="application/x-www-form-urlencoded" method="GET">
      <input type="text" name="one" value="" />
      <br /><input type="text" name="two" value="" />
      <br /><textarea rows="2" cols="25" name="three" placeholder="Enter Text Here"></textarea>
      <br /><input type="submit" value="Submit" />
    </form>
 <h3>POST</h3>   
    <form action="https://script.google.com/a/cooper/macros/s/AKfycbzlYgw2cw8q7u9qTxM/exec" enctype="application/x-www-form-urlencoded" method="POST">
      <input type="text" name="one" value="" />
      <br /><input type="text" name="two" value="" />
      <br /><textarea rows="2" cols="25" name="three" placeholder="Enter Text Here"></textarea>
      <br /><input type="submit" value="Submit" />
    </form>
  </body>
</html>

代码.gs:

function doGet(e){
  Logger.log('doGet: %s',JSON.stringify(e));
  if(e.parameter) {
    var data=e.parameter;
    handleFunction(data,'get');//This hardwires the term get to the ouput
  }
  return HtmlService.createHtmlOutputFromFile('testing');
}

function doPost(e){
  console.log('doPost Entry',JSON.stringify(e));
  if(e.postData.length!=-1) {
    var data=e.parameter;
    handleFunction(data,'post');//This hardwires the term post to the ouput
  }
  return ContentService.createTextOutput('doPost Return:' + JSON.stringify(e.postData.contents));
}

function handleFunction(data,source){
  console.log('handleFunction Entry: %s',JSON.stringify(data));
  var one=data.one;
  var two=data.two;
  var three=data.three;
  var ss=SpreadsheetApp.getActive();
  var sheet=ss.getActiveSheet();
  sheet.appendRow([source,one,two,three]);
}

function postit() {
  // DriveApp.getFiles() //I copied this from a Tanaike example.  I don't know if I need it still
  var ask=SpreadsheetApp.getUi().prompt("Enter first/second/third/method", SpreadsheetApp.getUi().ButtonSet.OK) 
  if(ask.getSelectedButton()==SpreadsheetApp.getUi().Button.OK) {
    var dA=ask.getResponseText().split('/');//Just an easy way to get 4 pieces of data at one time
    if(dA.length==4) {
      var url=ScriptApp.getService().getUrl();
      var data={"one":dA[0],"two":dA[1],"three":dA[2]};
      //the method is provide from the last term of the above prompt
      var options={"method":dA[3],"payload":data,"headers":{"Authorization":"Bearer " + ScriptApp.getOAuthToken()},"muteHttpExceptions": true};
      var resp=UrlFetchApp.fetch(url, options);
      Logger.log('UrlFetch Response: %s',resp);
    }
  }
}

动画:

这是我最终得到的,它在 Rhino 和 V8 中运行

function postit() {
  // DriveApp.getFiles() 
  var ask=SpreadsheetApp.getUi().prompt("Enter first/second/third/method", SpreadsheetApp.getUi().ButtonSet.OK); 
  if(ask.getSelectedButton()==SpreadsheetApp.getUi().Button.OK) {
    var dA=ask.getResponseText().split('/');
    if(dA.length==4) {  
      if(dA[3]=="POST") {
        var url=ScriptApp.getService().getUrl();
        var data={"one":dA[0],"two":dA[1],"three":dA[2]};
        var options={"method":dA[3],"payload":data,"headers":{"Authorization":"Bearer " + ScriptApp.getOAuthToken()},"muteHttpExceptions": true};
      }else if(dA[3]=="GET") {
        var url=Utilities.formatString('%s?one=%s&two=%s&three=%s',ScriptApp.getService().getUrl(),dA[0],dA[1],dA[2]);
        var data={"one":dA[0],"two":dA[1],"three":dA[2]};
        var options={"method":dA[3],"headers":{"Authorization":"Bearer " + ScriptApp.getOAuthToken()},"muteHttpExceptions": true};
      }
      var resp=UrlFetchApp.fetch(url, options);
    }
  }
}

【问题讨论】:

  • 相关:stackoverflow.com/a/56216818 (不如 Tanaike 的答案,但只是将其链接到这个问题)
  • 感谢这对于具有未知有效负载的更通用的解决方案很有用。老实说,这是我第一次真正深入了解 UrlFetch。我一直在查看其他人的问题一段时间,并且在这里和那里收集了一些东西,但没有自己做任何事情来弄清楚你不知道什么。

标签: google-apps-script urlfetch


【解决方案1】:

这个答案怎么样?请认为这只是几个可能的答案之一。

问题和解决方法:

我认为您的问题的原因是由于payload 为POST 和GET 方法请求的数据。在 UrlFetchApp 中,似乎当数据用作payload 时,使用POST 方法,即使method 是GET。为了以 GET 方式发送数据,请将它们添加到查询参数中。

(我之前以为用GET方法发送数据为payload时,数据可以发送为GET,但是关于这个,我只记得很模糊。对此我深表歉意。)

为了避免这种情况,下面的修改作为简单修改怎么样?

模式一:

在此模式中,查询参数用于 GET 方法。

修改脚本:

function postit() {
  // DriveApp.getFiles() //I copied this from a Tanaike example.  I don't know if I need it still
  var ask=SpreadsheetApp.getUi().prompt("Enter first/second/third/method", SpreadsheetApp.getUi().ButtonSet.OK) 
  if(ask.getSelectedButton()==SpreadsheetApp.getUi().Button.OK) {
    var dA=ask.getResponseText().split('/');//Just an easy way to get 4 pieces of data at one time
    if(dA.length==4) {
      var url=ScriptApp.getService().getUrl();

      // --- I modified below script.
      var potions = {};
      if (dA[3] == "POST") {
        var data={"one":dA[0],"two":dA[1],"three":dA[2]};
        //the method is provide from the last term of the above prompt
        options={"method":dA[3],"payload":data,"headers":{"Authorization":"Bearer " + ScriptApp.getOAuthToken()},"muteHttpExceptions": true};
      } else if (dA[3] == "GET") {
        options={"method":dA[3],"headers":{"Authorization":"Bearer " + ScriptApp.getOAuthToken()},"muteHttpExceptions": true};
        url += `?one=${dA[0]}&two=${dA[1]}&three=${dA[2]}`;
      }
      // ---

      var resp=UrlFetchApp.fetch(url, options);
      Logger.log('UrlFetch Response: %s',resp);
    }
  }
}

注意:

  • 请启用 V8。
  • 注释行的// DriveApp.getFiles() 用于通过脚本编辑器自动添加https://www.googleapis.com/auth/drive.readonly 的范围。这用于使用访问令牌访问 Web 应用程序。

参考资料:

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

【讨论】:

  • 我在第一个版本中使用了 Utilities.formatString() 而不是字符串字面量。
  • @Cooper 我不得不道歉,模式 2 不能用于这种情况。当我再次测试它时,我也可以确认它。在这种情况下,GET 方法被转换为 POST 方法。所以doPost 运行了。这是我的错误。我对此深表歉意。所以我删除了模式2。
  • 你没有什么可道歉的,我从我们在这个论坛上的协会中受益匪浅。谢谢。
  • 如果对其他人有帮助,请添加更多信息,因为我必须做一些研究来刷新我的记忆。对于 HTML/web 标准,GET 请求使用 URL 参数,这就是为什么您必须将提交值添加到 URL 的原因——就像上面的示例一样。此外,developers.google.com/apps-script/reference/url-fetch/… 还提到 GET 不接受 payload。
猜你喜欢
  • 2017-02-15
  • 1970-01-01
  • 2014-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多