为什么我不能让UrlFetchApp.fetch使用doGet()?

时间:2020-03-08 01:08:21

标签: google-apps-script urlfetch

如果我使用两种相同的形式,但一种形式使用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>

Code.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);
    }
  }
}

动画:

enter image description here

这就是我最终得到的结果,它可以在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);
    }
  }
}

1 个答案:

答案 0 :(得分:1)

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

问题和解决方法:

我认为您出现问题的原因是由于payloadPOST方法使用GET请求了数据。在UrlFetchApp中,似乎将数据用作payload时,即使methodGET时也使用POST方法。为了将数据作为GET方法发送,请将其添加到查询参数中。

((我认为当使用GET方法将数据以payload的形式发送时,以前可以以GET的形式来发送数据。但是关于这一点,我只有微弱的记忆力。对此我深表歉意。这个。)

为了避免这种情况,下面的修改作为简单修改如何?

模式1:

在此模式中,查询参数用于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 Apps。

参考文献:

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

相关问题