如何将文件上传Blob从HTML表单传递到服务器端Apps脚本? [英] How to pass file upload blob from HTML form to server-side Apps Script?

查看:58
本文介绍了如何将文件上传Blob从HTML表单传递到服务器端Apps脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

表单"标题下的Google 支持文章示例已损坏.摘自文章:

The Google support article example under the Forms heading is broken. From the article:

如果以表单元素作为参数调用服务器函数,则表单将成为一个单独的对象,其字段名称为键,字段值作为值.这些值都将转换为字符串,但文件输入字段的内容除外,这些内容成为Blob对象.

If you call a server function with a form element as a parameter, the form becomes a single object with field names as keys and field values as values. The values are all converted to strings, except for the contents of file-input fields, which become Blob objects.

我通过传递一个包含5个文本输入和一个文件的Form元素,然后在表单对象上记录 Object.keys()来进行测试.它仅返回5个文本字段,文件已从表单对象中剥离.尝试直接直接分配文件blob返回异常:无效参数:blob

I tested this by passing a Form element containing 5 text inputs and a file, then logging Object.keys() on the form object. It returned only the 5 text fields, the file was stripped from the form object. Attempting to assign the file blob directly returned Exception: Invalid argument: blob

如何将文件格式从客户端表单传递到服务器端Apps脚本?

How do I pass the file blob from the client-side Form to the server-side Apps Script?

编辑:为澄清起见,我还逐字粘贴了Google提供的示例.出现 Exception:无效参数:blob 时出错.

EDIT: To clarify, I also copy-pasted the example provided by Google verbatim. It errors with Exception: Invalid argument: blob.

要复制:

  1. 创建新的Google Apps脚本项目
  2. Index.html内容:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      // 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);

      function handleFormSubmit(formObject) {
        google.script.run.withSuccessHandler(updateUrl).processForm(formObject);
      }
      function updateUrl(url) {
        var div = document.getElementById('output');
        div.innerHTML = '<a href="' + url + '">Got it!</a>';
      }
    </script>
  </head>
  <body>
    <form id="myForm" onsubmit="handleFormSubmit(this)">
      <input name="myFile" type="file" />
      <input type="submit" value="Submit" />
    </form>
    <div id="output"></div>
 </body>
</html>

  1. Code.gs内容:

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function processForm(formObject) {
  var formBlob = formObject.myFile;
  var driveFile = DriveApp.createFile(formBlob);
  return driveFile.getUrl();
}

  1. 发布为Web App
  2. 提交包含任何文件的表格
  3. 在视图-> Stackdriver Logging-> Apps脚本仪表板中观察错误

推荐答案

我可以确认这在G-Suite Enterprise中不起作用.我不知道为什么,因为我找不到说明Google如何序列化数据的文档.它可能是浏览器/计算机的安全性设置,也可能是G-Suite中的某种设置.

I can confirm that this doesn't work in G-Suite Enterprise. I don't know why because I cannot find documentation that says how Google is serializing the data. It could be a browser/computer security setting or something in G-Suite.

但是,有一种更简单的方法可以满足您的需求.您可以将Google表单与文件上传问题一起使用,然后在其上创建表单提交触发器/事件,以将文件复制到团队/共享驱动器.如果您要将触发器附加到Google表单本身,请参见以下示例代码:

However, there is an easier way to accomplish your need. You can use a Google Form with a file upload question and then create an on form submit trigger/event on it to copy the file to a team/shared drive. Here is sample code if you want to attach the trigger to the Google Form itself:

// ID of the destnation folder to save the file in
var destinationFolderID = "10gkU_2V9iYy-VKudOCOjydEpoepPTgPv"

function saveFileToTeamDrive(e)
{
  // a place to save the URL of the uploaded file
  var fileID;

  // go through all of the responses to find the URL of the uploaded file
  e.response.getItemResponses().forEach(function(itemResponse){
    // once we find the question with the file
    if(itemResponse.getItem().getTitle() == "File Upload Test")
    {
      // get the file ID from the response
      fileID = itemResponse.getResponse();
      return;
    }
  });

  // stop if we didn't have one
  if(!fileID.length) return;

  // get the first index in the array
  fileID = fileID[0];

  // get the file
  var file = DriveApp.getFileById(fileID);

  // get the destination folder
  var destinationFolder = DriveApp.getFolderById(destinationFolderID);

  // make a copy
  var newFile = file.makeCopy(destinationFolder);

  Logger.log(newFile.getUrl());
}

您还可以将链接到Google表单的Google表格的 on表单提交事件附加到事件.我发现这种方式更容易,因为Google表单在表单上提交触发器/事件包含问题/答案的JSON,因此您无需遍历所有问题即可找到它.这也意味着如果提交失败,您可以重新运行.

You can also attach to the on form submit event of a Google Sheet that is linked to a Google Form. I find that way easier cause the Google Sheet on form submit trigger/event includes a JSON of the question/answers so you don't have to iterate all of them to find it. It also means you can re-run a submission if it failed.

一个重要的注意事项,如果您执行上述任何一项操作,则不会授予其他任何人对该代码的编辑权限.这是因为,一旦您创建并授权了触发器,任何拥有对代码的编辑访问权限的人都将能够使用它来访问您的Google云端硬盘(以及触发器有权使用的其他任何内容).请参阅确保链接到授权触发器的Google Apps脚本,以便其他人可以编辑以获取更多信息.

One important note, if you do either of these things do not give anyone else edit access to the code. This is because as soon as you create and authorize the trigger, anyone who has edit access to the code would be able to use it to gain access to your Google Drive (and anything else the trigger is authorized for). Please see securing a Google Apps Script linked to an authorized trigger so others can edit for more information.

这篇关于如何将文件上传Blob从HTML表单传递到服务器端Apps脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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