使用Gmail API网页JS发送带附件邮件遇files[i]未定义错误
解决Gmail API带附件发送邮件时的
Uncaught TypeError: files[i] is undefined错误 报错信息
Uncaught TypeError: files[i] is undefined
onload http://localhost:8000/:189
sendEmailWithAttachments http://localhost:8000/:182
debugger eval code:1
错误根源
- 闭包变量作用域问题:循环中使用
var i声明变量,var的作用域是函数级而非块级。当reader.onload异步回调触发时,循环已经执行完毕,i的值变为files.length,此时files[i]自然不存在,导致报错。 - 异步执行顺序问题:
FileReader.readAsDataURL是异步操作,原代码会在所有文件还未读取完成时就调用Gmail API发送请求,不仅附件内容为空,还会引发上述变量错误。
修复后的完整代码
async function sendEmailWithAttachments(to, subject, body, files) { const boundary = 'foo_bar_baz'; let multipart = ''; // 遍历文件,用await确保每个文件读取完成后再处理下一个 for (let i = 0; i < files.length; i++) { const file = files[i]; // 用Promise封装FileReader的异步操作 const base64Data = await new Promise((resolve) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { // 提取base64编码部分(去掉dataURL前缀) resolve(reader.result.split(',')[1]); }; }); // 拼接附件的MIME片段 multipart += `--${boundary}\r\n` + `Content-Type: ${file.type || 'application/octet-stream'}\r\n` + 'MIME-Version: 1.0\r\n' + 'Content-Transfer-Encoding: base64\r\n' + `Content-Disposition: attachment; filename="${file.name}"\r\n\r\n` + `${base64Data}\r\n`; } // 构建完整的邮件MIME内容 const emailContent = `Content-Type: multipart/mixed; boundary="${boundary}"\r\n` + 'MIME-Version: 1.0\r\n' + `to: ${to}\r\n` + `subject: ${subject}\r\n\r\n` + `--${boundary}\r\n` + 'Content-Type: text/plain; charset="UTF-8"\r\n' + 'MIME-Version: 1.0\r\n' + 'Content-Transfer-Encoding: 7bit\r\n\r\n' + `${body}\r\n\r\n` + `${multipart}` + `--${boundary}--`; // 处理Unicode字符编码:btoa无法直接处理非ASCII字符,需转义后再编码 const encodedEmail = btoa(unescape(encodeURIComponent(emailContent))); // 调用Gmail API发送邮件 const request = gapi.client.gmail.users.messages.send({ 'userId': 'me', 'resource': { 'raw': encodedEmail } }); request.execute((response) => { console.log(response); }); }
核心修复说明
- 块级作用域变量:将
var i改为let i,确保每次循环的i都是独立的块级变量,避免闭包导致的变量值异常。 - 异步流程控制:用
async/await配合Promise处理FileReader的异步操作,确保所有文件读取完成后再构建邮件内容,避免发送空附件。 - MIME规范优化:动态获取文件的
Content-Type,替代固定的application/octet-stream,更符合邮件标准。 - Unicode字符处理:通过
encodeURIComponent和unescape转义非ASCII字符,避免btoa编码失败。
内容的提问来源于stack exchange,提问作者Seles Salvo
相关产品推荐
相关产品推荐

