【问题标题】:HTML form submits twice if the onsubmit function runs longer than 10 seconds如果 onsubmit 函数运行时间超过 10 秒,HTML 表单会提交两次
【发布时间】:2020-12-01 18:58:48
【问题描述】:

我已经为此浪费了一整天的时间,而且我找到的搜索结果都没有帮助我。

我正在 Google 表格中编写脚本并在 Windows 10 操作系统上使用 Chrome 浏览器。我至少需要它在 Chrome 中运行,因为我公司的大多数人都使用 Chrome。

当我的代码完全生效时,一切正常,但我的 html 表单中的 onsubmit 操作调用了我的 gs TWICE 中的函数,我不知道为什么。

我看到的是;无论我的 html 文件或 gs 函数中的内容如何,​​如果我的函数需要十秒或更长时间才能执行,那么它会被第二次调用。这怎么可能?我做错了什么?

一步一步,这是我在做什么以及会发生什么。

首先,通过附加菜单,我调用生成包含表单的 HTML 模型窗口的初始函数。

function importPool() {
var ui = SpreadsheetApp.getUi();
var html = HtmlService.createHtmlOutputFromFile("importPool")
.setWidth(750)
.setHeight(300);
var dialog = ui.showModalDialog(html, "Import pool");
}

这会启动“importPool.html”

<!DOCTYPE html>
<html>
<head>
<base target="_top">

</head><body>
<form id="myForm" onsubmit="processForm(myForm);">
    <div style=" text-align: left; text-indent: 0px; padding: 0px 0px 0px 0px; margin: 0px 0px 0px 0px;">
        <table width="100%" border="1" cellpadding="2" cellspacing="2" style="background-color: #c0c0c0;">
    
            
            <tr valign="top">
                <td style="border-width : 0px;text-align: left"></td>
                <td style="border-width : 0px;text-align: right">
                    <input type="button" value="Cancel" onclick="google.script.host.close()"><input type="submit" value="Import">
      </td>
            </tr>
    
        </table>
    </div>
</form>
<script>
function processForm(formdata){
  google.script.run.processImport(formdata);
  google.script.host.close();
}
</script>
</body>

</html>

我单击“提交”按钮,然后在我的 gs 中调用我的 processImport 函数。出于测试目的,此函数仅包含

function processImport(form) {
Logger.log("I am running!");
Utilities.sleep(12000); 
}

正如我所提到的,如果我减少计时器以使函数执行时间少于十秒,那么每次单击“提交”按钮时,该函数只会运行一次。但是,如果该函数的执行时间超过十秒,则在我单击提交时它会运行两次。它第一次正常运行,然后几乎正好十秒后再次执行该函数,从上到下。

这可能是什么原因造成的?我确信我在做一些愚蠢的事情,但我找不到。请帮忙!

【问题讨论】:

    标签: javascript forms google-apps-script google-sheets form-submit


    【解决方案1】:

    改进建议

    1. 用事件侦听器替换内联事件处理程序(onsubmit=onclick= 属性)
    2. 使用google.script.run时使用withSuccessHandlerwithFailureHandler
    3. witchSuccessHandler的回调中添加google.script.host.close()
    4. &lt;script&gt;&lt;/script&gt; 的开头添加以下内容
    // Prevent forms from submitting.
    
      function preventFormSubmit() {
        var forms = document.querySelectorAll('form');
        for (var i = 0; i < forms.length; i++) {
          forms[i].addEventListener('submit', function(event) {
            event.preventDefault();
          });
        }
      }
      window.addEventListener('load', preventFormSubmit);
    

    来自https://developers.google.com/apps-script/guides/html/communication#forms

    请注意,在加载页面中的所有表单时,默认提交 preventFormSubmit 禁用的操作。这可以防止页面 发生异常时重定向到不准确的 URL。


    来自Introduction to events

    您可以找到许多事件处理程序属性的等效 HTML 属性;但是,你不应该使用这些——它们被认为是不好的做法。如果您只是非常快速地做某事,使用事件处理程序属性似乎很容易,但它们很快就会变得难以管理且效率低下。

    请记住,google.script.run 调用是异步的(它们之后的代码将在服务器端函数结束之前执行)

    相关

    【讨论】:

    • 遵循了您的所有建议,现在可以使用了!只运行一次,也没有更多的背景 HTML 错误。但是,还有一个问题……在所有这些中,“google.script.host.close();”应该在哪里?命令直播?如果我将它直接放在运行命令之后,则窗口会在触发该功能之前关闭。我觉得我可以添加一个计时器延迟,但感觉很笨重。
    • @Dave 放在withSuccessHandler的回调函数中
    • 就是这样!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2018-06-28
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-27
    • 1970-01-01
    • 2022-11-01
    相关资源
    最近更新 更多