简体   繁体   English

来自 web 应用程序中的 FileReader 创建的对象的数据然后传递给 Google Apps 脚本客户端返回空,未定义,null

[英]Data from objects created from FileReader in a web app then passed to Google Apps Script client-side return empty, undefined, null

My web app has a few file input elements where the user can upload any number of files of different types.我的 web 应用程序有几个文件输入元素,用户可以在其中上传任意数量的不同类型的文件。 I'm trying to store all data first in an array the same size of the number of input elements, where each item in the said array contains an array of data (filename, blob, mimetype) from each uploaded file.我试图首先将所有数据存储在一个数组中,该数组的大小与输入元素的数量相同,其中所述数组中的每个项目都包含来自每个上传文件的数据数组(文件名、blob、mimetype)。

The user can choose to upload or not, but if they don't, I still need to save some reference for that row with an empty upload by getting its data attribute (header).用户可以选择上传或不上传,但如果他们不上传,我仍然需要通过获取其数据属性(标题)为空上传的那一行保存一些参考。

The data appears in the browser console, but it returns undefined/empty/null when accessed from the client side of Google Apps Script.数据显示在浏览器控制台中,但从 Google Apps 脚本的客户端访问时返回未定义/空/空。 I'm not very familiar with the FileReader.我对 FileReader 不是很熟悉。

On the server side, I want to create a file in Google Drive from each blob and finally store the URL in Sheets.在服务器端,我想从每个 blob 在 Google Drive 中创建一个文件,最后将 URL 存储在表格中。

Thanks in advance!提前致谢!

function saveFormData(){

  var fileInputs = document.querySelectorAll('tr.result-row td > input.upload');
  var firstUploadIndex = fileInputs[0].parentElement.parentElement.getAttribute('data-index');

  //Loop through all upload rows
  var uploads = []; //will be array of arrays of multi-uploaded files; each item inside belongs to 1 column in db
  Array.from(fileInputs).forEach(input => {

    var files = input.files; //object file list

    if(files.length < 1){ //if there's no file in the upload input
      var header = input.getAttribute('data-uploadtype'); //save the header name as reference
      var fileData = [header, '', '', '']; 
      uploads.push(fileData);
    } else { //if there's a file/s in the upload input
      var innerUploads = []; //array of data for each file
      //Loop through all these files
      for(var i = 0; i < files.length; i++){
        
        var currentFile = files[i]; 

        if(!currentFile) return; //if no current file, just in case
        const fr = new FileReader();

        fr.onload = (e) => {
          var data = e.target.result.split(','); //split current file
          var fileData = { binary: data[1], mimeType: data[0].match(/:(\w.+);/)[1], filename: currentFile.name };
          innerUploads.push(fileData);
        }
        fr.readAsDataURL(currentFile);
      } //CLOSES FOR LOOP
      uploads.push(innerUploads);

    } //CLOSES IF
  
  }); //CLOSES FOR EACH LOOP

  google.script.run.saveToDrive(uploads);

} //CLOSES FUNCTION

This is what the upload interface looks like.这是上传界面的样子。 上传表格单元格内的元素

I believe your goal is as follows.我相信你的目标如下。

  • You want to retrieve the values from fileInputs and create an array of uploads including the values like [header, '', '', ''] and { binary: data[1], mimeType: data[0].match(/:(\w.+);/)[1], filename: currentFile.name } .您想要从fileInputs检索值并创建一个uploads数组,包括[header, '', '', '']{ binary: data[1], mimeType: data[0].match(/:(\w.+);/)[1], filename: currentFile.name }

When I saw your script, I thought that the reason for your current issue is due to that FileReader is run with the asynchronous process.当我看到你的脚本时,我认为你当前问题的原因是因为 FileReader 是在异步进程中运行的。 This has already been mentioned in my 1st comment.这已经在我的第一条评论中提到了。

When this is reflected in your script, how about the following modification?当这反映在您的脚本中时,以下修改如何?

Modified script:修改脚本:

Please modify your Javascript as follows.请修改您的Javascript如下。

function getFiles(file) {
  return new Promise((resolve, reject) => {
    const fr = new FileReader();
    fr.onload = e => {
      const data = e.target.result.split(",");
      const obj = { binary: data[1], mimeType: data[0].match(/:(\w.+);/)[1], fileName: file.name };
      resolve(obj);
    }
    if (file) {
      fr.readAsDataURL(file);
    } else {
      reject("No file");
    }
  });
}

async function saveFormData() {
  var fileInputs = document.querySelectorAll('tr.result-row td > input.upload');
  // var firstUploadIndex = fileInputs[0].parentElement.parentElement.getAttribute('data-index'); // This is not used in your showing script.
  var uploads = [];
  var ar = Array.from(fileInputs);
  for (var i = 0; i < ar.length; i++) {
    var files = ar[i].files;
    if (files.length == 0) {
      var header = ar[i].getAttribute('data-uploadtype'); //save the header name as reference
      var fileData = [header, '', '', ''];
      uploads.push(fileData);
    } else {
      for (var j = 0; j < ar[i].files.length; j++) {
        var res = await getFiles(ar[i].files[j]).catch(err => console.log(err));
        uploads.push(res);
      }
    }
  }

  console.log(uploads); // You can confirm the value in the log.

  google.script.run.saveToDrive(uploads);
}
  • Unfortunately, I cannot know your actual HTML. So, I modified your script by guessing your HTML. If an error occurs, please provide the HTML. By this, I would like to confirm it.不幸的是,我不知道你的实际HTML。所以,我修改了你的脚本,猜测你的HTML。如果出现错误,请提供HTML。据此,我想确认一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Google Apps脚本中从服务器端(.gs)传递到客户端(html)时,已知类型的变量变为“未定义” - Variable of known type becomes “undefined” when passed from server side (.gs) to client-side(html) in Google Apps Script 从Google Apps脚本调用客户端功能 - Calling client-side function from google apps scrip 如何从 Google Apps Script Web App 返回图像? - How to return an image from a Google Apps Script Web App? Datetime 似乎破坏了 Google Apps Script 客户端反序列化 - Datetime seems to break Google Apps Script client-side deserialization 从已部署的 Web 应用程序(Google Apps 脚本)下载创建的 Google Doc - Download a created Google Doc from a deployed web app (Google Apps Script) 在 Google Apps 脚本中从服务器到客户端进行通信 - Communicate from server to client side in Google Apps script 从 Google Apps 脚本调试客户端代码 - Debugging client side code from Google Apps Script 在Google Script网络应用中为客户端格式化API数据 - Formatting API data for client side in a Google Script web app 如何使用 HtmlService 为 Web 应用程序存储客户端数据? - How to store data client-side for web app / with HtmlService? 试图了解Google Apps脚本中服务器端和客户端的概念 - Trying to understand the notion of server-side and client-side in Google Apps Script
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM