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

使用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

错误根源

  1. 闭包变量作用域问题:循环中使用var i声明变量,var的作用域是函数级而非块级。当reader.onload异步回调触发时,循环已经执行完毕,i的值变为files.length,此时files[i]自然不存在,导致报错。
  2. 异步执行顺序问题: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 12:05:01