问题
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 ofhttps://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