HtmlService无法从doPost()工作 - 需要脚本化异步备用

时间:2013-03-16 03:30:27

标签: google-apps-script

我想使用doPost()和HtmlService作为异步调度程序来调用其他函数。异步功能对于性能非常重要 - 无需同步等待电子表格操作完成,因此这就是HtmlService的用途。 这是我的代码方式:

 function doGet(e) {
      var app = UiApp.createApplication();
  var button = app.createButton('Click Me');
  app.add(button);
  var handler = app.createServerHandler('myClickHandler');
  button.addClickHandler(handler);
  return app;
}

function myClickHandler(){
  sendHttpPostSelf();
}
function doSomething() {
  Logger.log('I was called Now!');
  return;
}
function sendHttpPostSelf() {
  var payload = {
      "name" : "name",
      "comment" : "comment",
      "screenshot" : "screenshot"
  };
  var options = {
      "method" : "post",
      "payload" : payload
    };
var url="https://script.google.com/macros/s/AKfycbzlVoiDQMbLe4yliErDoNub6A0m3tijSfPAUMEBENgIikQnLQ_H/exec";
var resp=UrlFetchApp.fetch(url,options);
Logger.log(resp.getContentText());//.getContent());
} 
function doPost(e){
  var dbg;
  var dbg=true;
  if (dbg==true)for (var i in e.parameter)Logger.log("FormSubmit:doPost "+ i + ": " + e.parameter[i]);
  return HtmlService.createHtmlOutputFromFile("myFile.html");
}

//ANd HERE IS myFile.html
<script>
 function onFailure(error) {
   //alert('Error will Robinson!: '+error.message);
     Logger.log('Error will Robinson!: '+error.message);
  }
  function onSuccess(error) {
    //alert('Gotter Done');
    Logger.log("FormSubmit:doPost",'Gotter Done');
  }
  google.script.run.withSuccessHandler(onSuccess).withFailureHandler(onFailure).doSomething();
</script>

httpPostSelf()工作正常,doPost()接收parms很好但我的问题是 HtmlService.createHtmlOutputFromFile(“myFile.html”)没有正确调用doSomething()? 我只在Logger.log中看到很多神秘的caja解析 - 原始问题的结束 -

问题添加
亲爱的科里:

感谢您对doPost()的反馈,而不是处理HtmlService和您提出的异步示例。 你是对的,按钮点击事件是异步..但我的问题仍然没有答案。澄清, 请允许我进一步详细说明我的问题。我需要工作的是对Web应用程序的异步脚本调用(听起来像我猜的AJAX)。除了异步之外,所有工作都在我的示例脚本中。在我之前的示例中使用了另一个URL来调用单独的Web应用程序而不是自我发布:

var url="https://script.google.com/a/macros/commet.com/s/AKfycbwJ4WM3U5POEWF9XqFzjaV_9TiNLspKb7kePAih59vsWllA0og/exec";

异步对性能至关重要,因为我有2000多行电子表格代码来执行基本工作表操作:插入,删除,更新,移动,排序..我将脚本很好地打包到带有方法的对象中。工作表ops脚本当前与站点中的UiApp脚本一起打包,并且可以同步调用。在经历了许多痛苦的重写之后,一些更复杂的操作(排序和移动)仍需要7秒才能完成。

我想将工作表操作脚本迁移到电子表格Web应用程序。工作表/ Web应用程序应该可以从我的站点UiApp中调用异步。例如,当我的网站要求排序时,它将简单地将带有parms的sendHttpPost释放到Web App,然后该站点将继续完成其GUI业务(进行客户端排序)而无需等待7秒的电子表格完成它的排序。 WaLaa!

使用parms正确传递的Web应用程序在我的示例脚本中工作但不幸的是(对我而言)UrlFetchApp.fetch是同步的。这就是我尝试异步HtmlService-google.script.run的原因。我尝试使用HtmlService作为Web应用程序调用doGet(),并且无法使用UrlFetchApp.fetch。 HtmlService作为Web App工作的唯一方法是从带有表单提交的按钮调用...我需要一个可编写脚本的界面。

UrlFetchApp.fetch的任何可编写脚本的替代方法 - HtmlService?

评论HtmlService Web App Access
以下是我在Web应用程序中运行HtmlService时的测试结果:
的doPost()
- 使用FormPanel中的“提交”按钮提交时工作 - 使用UrlFetchApp.fetch(脚本访问所需)提交时不起作用 评论:任何让doPost()与UrlFetchApp.fetch一起使用的方法都可以很好地了解编程表单!

的doGet()
- 来自浏览器 - 网址 - 使用UrlFetchApp.fetch(脚本访问所需)提交时不起作用 如果有任何不准确,请回复脚本示例。我需要的是UrlFetchApp.fetch脚本访问。

2 个答案:

答案 0 :(得分:2)

您正尝试通过doPost从UiApp联系HtmlService,这将无法正常工作。 UiApp的doPost只能接受UiApp响应,而HtmlService甚至不使用doPost - 它只使用google.script.run语法。您所看到的是客户端上的UiApp代码完全被HtmlService类型的响应所困惑。

但我认为你可能会对这两种服务的工作方式感到困惑,因为UiApp ServerHandler回调和HtmlService google.script.run异步调用服务器脚本而不需要你做一些自定义或棘手的事情。没有必要混合和匹配这两者,根本不需要涉及doPost - 这是专门用于通过UiApp上传文件(这就是为什么HtmlService不支持它,因为它有一个更简单的语法来上传文件) 。

这是UiApp中的异步调度程序:

function doGet() {
  var app = UiApp.createApplication();
  app.add(app.createButton("run foo", app.createServerHandler("foo")));
  app.add(app.createButton("run bar", app.createServerHandler("bar")));
  return app;
}
function foo() { Logger.log("ran foo!");  }
function bar() { Logger.log("ran bar!");  }

在HtmlService中也是如此:

function doGet() {
  return HtmlService.createHtmlOutput(
      "<button onclick='google.script.run.foo()'>run foo</button>" +
      "<button onclick='google.script.run.bar()'>run bar</button>"); 
}
function foo() { Logger.log("ran foo!");  }
function bar() { Logger.log("ran bar!");  }

要回答下面的评论,请在UiApp中通过addCallbackElement将值从客户端发送到服务器。在HtmlService中,您只需向服务器函数添加参数:

function doGet() {
  return HtmlService.createHtmlOutput(
      "<button onclick='var foo = document.getElementById(\'myTextBox\').value; google.script.run.foo(123, foo)'>run foo</button>"
}
function foo(x, y) { Logger.log("ran foo with params " + x + " and + "y");  }

那应该记录“使用params 123和 myTextBox的内容”运行foo。您应该可以从那里进行概括(我建议您也阅读用户指南。)

答案 1 :(得分:1)

当您在自己制作的HtmlTemplates中运行脚本时,他们无法访问Apps脚本库(但您可以调用您的Apps脚本功能)。例如,您无法从Html页面调用Logger.log()。您应该使用console.log()。这将记录到您的Web控制台。 (Chrome中的Ctrl + Shift + J