为什么我不能让我的 UrlFetchApp.fetch 使用 doGet()?
Why can't I get my UrlFetchApp.fetch to use the doGet()?
如果我使用两种相同的形式,但一种使用 GET 方法,一种使用 POST 方法,当我 运行 时,一个使用 doGet,另一个使用做邮政()。但是当我通过提供来自提示的输入对 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);
}
}
}
动画:
这是我最终得到的结果,它在 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);
}
}
}
这个答案怎么样?请将此视为几个可能的答案之一。
问题和解决方法:
我认为您的问题的原因是由于 payload
为 POST
和 GET
方法请求数据。在UrlFetchApp,似乎当数据被用作payload
时,使用POST方法,即使method
是GET
。为了以 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 应用程序。
参考文献:
如果我误解了您的问题并且这不是您想要的方向,我深表歉意。
如果我使用两种相同的形式,但一种使用 GET 方法,一种使用 POST 方法,当我 运行 时,一个使用 doGet,另一个使用做邮政()。但是当我通过提供来自提示的输入对 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);
}
}
}
动画:
这是我最终得到的结果,它在 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);
}
}
}
这个答案怎么样?请将此视为几个可能的答案之一。
问题和解决方法:
我认为您的问题的原因是由于 payload
为 POST
和 GET
方法请求数据。在UrlFetchApp,似乎当数据被用作payload
时,使用POST方法,即使method
是GET
。为了以 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 应用程序。
参考文献:
如果我误解了您的问题并且这不是您想要的方向,我深表歉意。