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
相关产品推荐
相关产品推荐

