HtmlService不能从doPost()开始工作 - 需要脚本化的异步替代方案 [英] HtmlService not working from doPost() - scriptable async alternative wanted

查看:116
本文介绍了HtmlService不能从doPost()开始工作 - 需要脚本化的异步替代方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用HtmlService的doPost()作为异步调度器来调用其他函数。异步功能对于性能非常重要 - 无需等待电子表格操作完成,因此这就是HtmlService的用途。
这里是我的代码明智的:
$ b $ pre $ 函数doGet(e){
var app = UiApp.createApplication();
var button = app.createButton('Click Me');
app.add(button);
var handler = app.createServerHandler('myClickHandler');
button.addClickHandler(handler);
返回应用程序;
}

函数myClickHandler(){
sendHttpPostSelf();

函数doSomething(){
Logger.log('我被称为Now!');
return;

函数sendHttpPostSelf(){
var payload = {
name:name,
comment:comment,
截图:截图
};
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());
}
函数doPost(e){
var dbg;
var dbg = true;
if(dbg == true)for(var i in e.parameter)Logger.log(FormSubmit:doPost+ i +:+ e.parameter [i]);
返回HtmlService.createHtmlOutputFromFile(myFile.html);
}

//这里是myFile.html
< script>
函数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解析

- 原始问题结束 -



问题补充

亲爱的Corey:



感谢您对doPost()未处理HtmlService和您的提出了异步的例子。
您是正确的,按钮点击事件是异步..但我的问题仍然没有答案。为了澄清,
允许我请进一步详细阐述我的问题。我需要工作的是一个异步脚本调用Web应用程序(听起来像AJAX我猜)。所有的作品在我的示例脚本中除了异步。在我之前的例子中,我使用了一个替代URL来调用一个单独的Web应用程序,而不是一个自我贴文:

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

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



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



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



任何支持UrlFetchApp.fetch的脚本替代品 - HtmlService?



注释HtmlService Web App Access

这里是我的测试结果,当HtmlService从Webapp运行时:

doPost()

- 在FormPanel中使用Submit按钮提交时的作品>
- 与UrlFetchApp.fetch一起提交时不起作用(需要脚本访问)

评论:任何获得doPost()与UrlFetchApp.fetch一起使用的方法对于编程知道得很好形式!


doGet()

- 从浏览器url中获得 -
- 使用UrlFetchApp.fetch提交时不起作用需要脚本访问)

如果有任何不准确的地方,请回复脚本示例。我需要的是UrlFetchApp.fetch脚本访问。

解决方案

您试图通过doPost与UiApp联系HtmlService, 。 UiApp的doPost只能接受UiApp响应,而HtmlService甚至不使用doPost--它仅使用google.script.run语法。你所看到的是客户端上的UiApp代码完全被HtmlService类型的响应所困惑。 但是我认为你可能对这两种服务的工作方式感到困惑,因为UiApp ServerHandler回调函数和HtmlService google.script.run异步调用服务器脚本而不需要你做一些自定义或棘手的事情。没有必要混合和匹配两者,也不需要参与doPost - 这是专门用于通过UiApp上传文件的(这就是为什么HtmlService不支持它,因为它具有更简单的上传文件的语法) 。



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

 函数doGet ){
var app = UiApp.createApplication();
app.add(app.createButton(run foo,app.createServerHandler(foo)));
app.add(app.createButton(run bar,app.createServerHandler(bar)));
返回应用程序;
}
函数foo(){Logger.log(ran foo!); }
function bar(){Logger.log(ran bar!); }

在HtmlService中这里是一样的:

 函数doGet(){
return HtmlService.createHtmlOutput(
< button onclick ='google.script.run.foo()'>运行foo< / button>+
< button onclick ='google.script.run.bar()'>运行栏< / button>);
}
函数foo(){Logger.log(ran foo!); }
function bar(){Logger.log(ran bar!);为了回答下面的评论,在UiApp中,通过addCallbackElement将客户端的值发送到服务器。在HtmlService中,您只需将参数添加到您的服务器函数中:

 函数doGet(){
return HtmlService.createHtmlOutput(
< button onclick ='var foo = document.getElementById(\'myTextBox\')。value; google.script.run.foo(123,foo)'> run foo< / button>

函数foo(x,y){Logger.log(ran foo with params+ x +and +y);}

这应该记录使用params 123和 myTextBox的内容运行foo。你应该能够从那里推广我建议阅读用户指南。)


I'd like to use doPost() with HtmlService as an async dispatcher to call other functions with. The async capability is important for performance - not having to wait synchronously for a spreadsheet operation to complete, so that is what the HtmlService is for. Here is what I have code-wise:

 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>

The httpPostSelf() works okay and doPost() receives the parms fine but my problem is that HtmlService.createHtmlOutputFromFile("myFile.html") does not call doSomething() properly? I only see a lot of cryptic caja parsing in Logger.log
--END OF ORIGINAL QUESTION--

Question Addition
Dear Corey:

Appreciate your feedback on doPost() not handling HtmlService and your proposed async examples. You are correct, button-click events are async..but my question is still unanswered. To clarify, allow me to please elaborate further on my question. What I need to work is an async script call to a web app(sounds like AJAX I guess). All works in my sample script except for the async. An alternative URL is used then in my previous example to call a separate web app instead of a self-post:

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

The async is critical to performance because I have 2000 plus lines of spreadsheet code to conduct basic sheets operations: inserts, deletes, updates, moves, sorts..I have the script nicely packaged into objects with methods. The sheet ops script is currently packaged with the UiApp script in Sites and callable synchronously. After many painful rewrites, some of the more complex ops(sorts and moves) are still taking up to 7 seconds to complete.

I want to migrate the sheet op script to spreadsheet Web Apps. The sheet op/Web App should be callable async from my Site UiApp. For example, when my Site calls for a sort it will simply unleash a sendHttpPost with parms to the Web App and then the the Site will carry on about completing its GUI business(doing the sort client-side) without waiting 7 seconds for the spreadsheet to complete its sort. WaLaa!

The web app with parms passing correctly work in my sample script but the UrlFetchApp.fetch unfortunately(for me) is synchronous. THAT is why I attempted the async HtmlService-google.script.run. I tried calling doGet() with HtmlService as a web app and that does not work either using UrlFetchApp.fetch. The only way HtmlService works as a Web App is when called from a push-button with a form submit...I need a scriptable interface.

Any scriptable alternatives to UrlFetchApp.fetch - HtmlService?

Comment HtmlService Web App Access
Here are my test results for when HtmlService works from a Webapp:
doPost()
- works when submitted with Submit button in FormPanel
- does not work when submitted with UrlFetchApp.fetch(needed for script access)
Comment: Any way to get doPost() to work with UrlFetchApp.fetch would be great to know for programming forms!

doGet()
- works from a browser-url
- does not work when submitted with UrlFetchApp.fetch(needed for script access)
If any is inaccurate please reply with script examples. What I need is UrlFetchApp.fetch script access.

解决方案

You are trying to contact HtmlService from UiApp via doPost, which will not work. UiApp's doPost can only accept UiApp responses, and HtmlService doesn't even use doPost - it uses the google.script.run syntax exclusively. What you are seeing is the UiApp code on the client being completely confused by the HtmlService-type response.

But I think you are perhaps confused about how both of these services work, as both UiApp ServerHandler callbacks and HtmlService google.script.run call server scripts asynchronously without any need for you to do something custom or tricky. There is no need to mix and match the two, and no need to involve doPost at all - that is exclusively intended for uploading files via UiApp (which is why HtmlService doesn't support it, since it has a simpler syntax for uploading files).

This is an async dispatcher in 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!");  }

And here is the same in 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!");  }

To answer a comment below, in UiApp you send values from the client to the server via addCallbackElement. In HtmlService, you just add parameters to your server function:

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

That should log "ran foo with params 123 and contents of myTextBox". You should be able to generalize from there (and I'd suggest reading the user guide as well.)

这篇关于HtmlService不能从doPost()开始工作 - 需要脚本化的异步替代方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆