Google sheets modal 不提交表单,但作为一个独立的网络应用程序,它正在工作

Google sheets modal doesn't submit form but as a standalone webapp it's working

我有一个自定义 UI 函数,它会在我的 Google 表格文件中打开一个模式对话框。模式是一个简单的 HTML 表单,允许用户从本地硬盘选择一个文件,将其上传到 Google 驱动器。此表单的 HTML 部分如下:

<form>
  <input type="file" name="theFile" id="file-check" accept="image/*">
  <input type="button" class="btn btn-info"  value="Add photo" id="add-image">
</form>

发送数据的代码如下:

$("#add-image").click(function(){
      var val = $('#file-check').val();
      if (val == ''){alert('Choose a file to upload');return;}
      $('#add-image').attr("disabled", true);
      $('#add-image').attr("value", "Adding... please wait.");
google.script.run.withSuccessHandler(refreshIt).withFailureHandler(show_error).uploadImage(this.parentNode);
    });

但是当我提交表单时,服务器的响应是这样的:

{theFile=null}

我尝试将此模态对话框设置为独立的网络应用程序,它运行正常... 来自独立webapp的服务器响应如下:

{theFile=FileUpload}

文件正在上传,没有任何问题!

为什么它作为独立的 webapp 正常工作,但将 null 作为模态对话框发送?

问题和解决方法:

Why is it working normally as a standalone webapp but sending the null as a modal dialog?

我认为这个问题的原因是由于当前的规范。 V8 运行时发布后,有一个错误,当文件从 HTML 形式发送到 Google Apps 脚本端使用 google.script.run 时,文件 blob 是无效数据。但是,在 2021 年 11 月 26 日,这个错误可能会被删除。 Ref But, when I tested this, it was found that this bug could be removed for Web Apps, and this bug cannot be removed for the dialog and sidebar. Ref 这已报告给问题跟踪器。相信这个bug会在以后的更新中得到解决。

在当前阶段,为了上传带有对话框和侧边栏的文件,需要使用变通方法。在这个答案中,我想提出一个解决方法。当你的脚本修改后,变成如下。

修改后的脚本:

发件人:

$("#add-image").click(function(){
      var val = $('#file-check').val();
      if (val == ''){alert('Choose a file to upload');return;}
      $('#add-image').attr("disabled", true);
      $('#add-image').attr("value", "Adding... please wait.");
google.script.run.withSuccessHandler(refreshIt).withFailureHandler(show_error).uploadImage(this.parentNode);
    });

收件人:

$("#add-image").click(function(){
  var val = $('#file-check').val();
  if (val == ''){alert('Choose a file to upload');return;}
  $('#add-image').attr("disabled", true);
  $('#add-image').attr("value", "Adding... please wait.");

  const file = this.parentNode.theFile.files[0];
  const fr = new FileReader();
  fr.onload = function(e) {
    google.script.run.withSuccessHandler(refreshIt).withFailureHandler(show_error).uploadImage([[...new Int8Array(e.target.result)], file.type, file.name]);
  };
  fr.readAsArrayBuffer(file);
});
  • 在这种情况下,Google Apps Script的函数uploadImage可以修改如下。不幸的是,我看不到您当前的 uploadImage 脚本。因此,请使用以下示例修改您的脚本。

      function uploadImage(obj) {
        const blob = Utilities.newBlob(...obj);
        DriveApp.createFile(blob);
    
        return "done"; // Please set your expected return value.
      }
    

参考文献: