You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Apps Script表单文件上传:异步FileReader问题排查

解决FileReader异步处理问题,正确返回文件对象

问题根源

你的saveFileJS函数中,FileReader的onload是异步事件回调,直接用await修饰回调函数无效——因为await只能等待Promise对象,而事件回调不属于Promise。这导致函数提前返回了空的retorno,服务器端接收不到有效的bytes属性,从而抛出TypeError。

修正方案:用Promise包装FileReader操作

将FileReader的异步逻辑包装成Promise,这样就能通过async/await等待文件读取完成,确保返回处理后的文件对象:

async function saveFileJS(f) {
  console.log("arquivo: " + f);
  const file = f.files[0];

  // 将FileReader操作包装为Promise
  return new Promise((resolve) => {
    const fr = new FileReader();
    fr.onload = function(e) {
      const obj = {
        filename: file.name,
        mimeType: file.type,
        bytes: [...new Int8Array(e.target.result)]
      };
      console.log("file: ", obj);
      console.log("nome do arquivo: " + obj.filename);
      resolve(obj); // 读取完成后返回文件对象
    };
    fr.readAsArrayBuffer(file);
  });
}

调用方式

在预处理文件输入项时,确保用await调用saveFileJS,等待Promise完成后再获取结果:

// 示例:在preparaVetores中处理文件
async function preparaVetores() {
  // ... 其他表单字段处理逻辑 ...
  
  // 处理第一个文件输入
  const fotoInput = document.getElementById('foto-input');
  const fotoObj = await saveFileJS(fotoInput);
  
  // 处理第二个文件输入
  const curriculoInput = document.getElementById('curriculo-input');
  const curriculoObj = await saveFileJS(curriculoInput);
  
  // 将文件对象加入要发送的数组
  const formData = [...其他字段, fotoObj, curriculoObj];
  
  // 发送到服务器端
  google.script.run.finalizarFormulario(formData);
}

服务器端验证

确保你的saveFile函数能正确接收文件对象:

function saveFile(obj, destino) {
  // 从obj中读取字节、MIME类型和文件名创建文件
  const file = DriveApp.createFile(Utilities.newBlob(obj.bytes, obj.mimeType, obj.filename));
  file.moveTo(DriveApp.getFolderById(destino));
  return file.getUrl();
}

这样修改后,saveFileJS会等待文件读取完成再返回有效对象,服务器端就能正常读取obj.bytes属性,避免报错。

内容的提问来源于stack exchange,提问作者David Paiva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 06:47:37