0

我想使用带有 HtmlService 的 doPost() 作为异步调度程序来调用其他函数。异步功能对性能很重要——不必同步等待电子表格操作完成,这就是 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() 接收参数很好,但我的问题是 HtmlService.createHtmlOutputFromFile("myFile.html") 没有正确调用 doSomething() ?我只在 Logger.log 中看到很多神秘的 caja 解析
--END OF ORIGINAL QUESTION --

问题补充
亲爱的科里:

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

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

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

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

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

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

评论 HtmlService Web 应用程序访问
以下是我的测试结果,当 HtmlService 从 Web 应用程序工作时:
doPost()
- 使用 FormPanel 中的提交按钮提交时
工作 - 使用 UrlFetchApp.fetch 提交时不起作用(脚本访问需要)
评论:任何方式让 doPost() 与 UrlFetchApp.fetch 一起工作对于编程表单来说非常好!

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

4

2 回答 2

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

那应该记录“run foo with params 123 and contents of myTextBox ”。您应该能够从那里进行概括(我建议您也阅读用户指南。)

于 2013-03-17T03:02:38.063 回答
1

当您在您制作的 HtmlTemplates 中运行脚本时,它们无权访问 Apps 脚本库(但您可以调用您的 Apps 脚本函数)。例如,您不能Logger.log()从您的 Html 页面调用。你应该使用console.log(). 这将登录到您的 Web 控制台。(在 Chrome 中是Ctrl+ Shift+ )。J

于 2013-03-16T16:08:13.850 回答