Why can't I get my UrlFetchApp.fetch to use the doGet()?

≯℡__Kan透↙ 提交于 2021-01-28 00:51:09

问题


If I use two forms that are both the same but one has a method of GET and one has a method of POST when I run them one uses the doGet and the other uses the doPost(). But that doesn't happen when I do the same thing with the UrlFetch() command by providing the input from a Prompt.

The html:

The top form is a GET and the bottom form is 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);
    }
  }
}

Animation:

This what I ended up with and it runs in Rhino and 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:


How about this answer? Please think of this as just one of several possible answers.

Issue and workaround:

I think that the reason of your issue is due to the data is requested with payload for POST and GET methods. At UrlFetchApp, it seems that when the data is used as payload, POST method is used, even when method is GET. In order to send the data as GET method, please add them to the query parameter.

(I thought that when the data is send as payload with the GET method, the data could be sent as GET before. But about this, I only had a faint memory. I apologize for this.)

In order to avoid this, how about the following modification as the simple modification?

Pattern 1:

In this pattern, the query parameter is used for the GET method.

Modified script:

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

Note:

  • Please enable V8.
  • // DriveApp.getFiles() of the comment line is used for automatically adding the scope of https://www.googleapis.com/auth/drive.readonly with the script editor. This is used for accessing to Web Apps using the access token.

References:

  • Class UrlFetchApp

If I misunderstood your issue and this was not the direction you want, I apologize.



来源:https://stackoverflow.com/questions/60583673/why-cant-i-get-my-urlfetchapp-fetch-to-use-the-doget

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!