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

NextJS+Axios+PHPMailer发送邮件附件失败求助

解决NextJS+Axios+PHPMailer邮件附件无法传递的问题

前端问题与修正

你的前端核心问题是用JSON格式传递文件,但File对象无法被JSON序列化,且强制设置了application/json请求头,导致后端无法正确解析文件。必须改用FormData封装表单数据,这是文件上传的标准方式。

修改后的前端状态管理与提交代码

const [forma, setForma] = useState({
  name: '',
  mail: '',
  mobile:'',
  department:"",
  title:"",
  file: null // 初始值改为null,匹配File对象类型
})

const handleSubmita = (e) => {
  e.preventDefault()
  console.log(forma)
  setSpinner(true)

  // 用FormData封装所有表单数据
  const formData = new FormData()
  formData.append('name', forma.name)
  formData.append('mail', forma.mail)
  formData.append('mobile', forma.mobile)
  formData.append('department', forma.department)
  formData.append('title', forma.title)
  if (forma.file) {
    formData.append('app-file', forma.file) // key与input的name属性保持一致
  }

  axios({
    method: 'post',
    url: process.env.NEXT_PUBLIC_URL_A,
    // 不要手动设置content-type,让Axios自动处理multipart/form-data格式
    data: formData,
  })
  .then((result) => {
    console.log(result.data)
    if (result.data == '200') {
      setSpinner(false)
      setResultqform(true)
    } else {
      setSpinner(false)
      setError(true)
    }
  })
  .catch((error) => console.log('error'))
}

表单部分无需修改,保持原有结构即可。

后端问题与修正

后端核心问题是错误解析请求格式,且对$_FILES的引用逻辑完全错误。multipart/form-data格式的请求会被PHP自动解析到$_POST和$_FILES全局变量,无需手动读取php://input。

修改后的后端PHP代码

<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type');

use PHPMailer\PHPMailer\PHPMailer;

// 检查必填字段和文件上传状态
if (
    isset($_POST['name']) &&
    isset($_POST['mail']) &&
    isset($_POST['title']) &&
    isset($_POST['mobile']) &&
    isset($_POST['department']) &&
    isset($_FILES['app-file']) && $_FILES['app-file']['error'] === UPLOAD_ERR_OK
) {
    // 转义HTML特殊字符,防止XSS
    $name = htmlentities($_POST['name']);
    $mail = htmlentities($_POST['mail']);
    $title = htmlentities($_POST['title']);
    $mobile = htmlentities($_POST['mobile']);
    $department = htmlentities($_POST['department']);

    // 获取上传文件基础信息
    $fileTmpPath = $_FILES['app-file']['tmp_name'];
    $fileName = $_FILES['app-file']['name'];
    $fileSize = $_FILES['app-file']['size'];
    $fileType = $_FILES['app-file']['type'];

    // 验证文件类型和大小(可选,按需调整)
    $allowedTypes = ['application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/pdf'];
    if (!in_array($fileType, $allowedTypes) || $fileSize > 5 * 1024 * 1024) { // 限制5MB以内
        echo "Invalid file type or size";
        exit;
    }

    // 可选:将文件保存到服务器留档
    $uploadDir = 'tmp/';
    if (!is_dir($uploadDir)) {
        mkdir($uploadDir, 0755, true);
    }
    $destPath = $uploadDir . $fileName;
    if (!move_uploaded_file($fileTmpPath, $destPath)) {
        echo "Failed to save file";
        exit;
    }

    require_once 'PHPMailer/PHPMailer.php';
    require_once 'PHPMailer/SMTP.php';
    require_once 'PHPMailer/Exception.php';

    $mail = new PHPMailer(true); // 启用异常处理
    date_default_timezone_set('Europe/London');
    $now = date_create()->format('Y-m-d H:i:s');

    try {
        $mail->isSMTP();
        $mail->Host = $Host;
        $mail->SMTPAuth = true;
        $mail->Username = $uname;
        $mail->Password = $pass;
        $mail->SMTPSecure = 'ssl';
        $mail->Port = $port;
        $mail->CharSet = 'UTF-8';

        $mail->setFrom($mailer, 'Mailer');
        $mail->addAddress($recipent, $recipent_info);
        $mail->addReplyTo($mail, $name);

        // 添加附件:已保存用destPath,无需保存直接用$fileTmpPath即可
        $mail->addAttachment($destPath, $fileName);

        $mail->isHTML(true);
        $mail->Subject = 'Test';
        $mail->Body = "<b>{$name}</b> =name<br><br>";
        $mail->Body .= "<b>department:</b> {$department}<br><br>";
        $mail->Body .= "<b>title:</b> {$title}<br><br>";
        $mail->Body .= "<b>Mobile:</b> {$mobile}<br><br>";
        $mail->Body .= "<b>Mail:</b> {$mail}<br><br>";
        $mail->Body .= "<b>Time: </b>{$now}";

        $mail->send();
        echo '200';
    } catch (Exception $e) {
        echo "Error! Mailer Error: {$mail->ErrorInfo}";
    }
} else {
    echo "Missing required fields or file upload failed";
}
?>

关键修正点说明

  1. 前端改用FormData传递数据,请求头由Axios自动适配multipart/form-data。
  2. 后端删除手动解析请求的逻辑,直接使用PHP自动处理的$_POST和$_FILES。
  3. 正确引用上传文件:$_FILES['app-file']对应前端input的name属性。
  4. 添加文件上传验证(错误码、类型、大小),避免无效文件引发错误。
  5. 支持两种附件添加方式:保存到服务器后添加,或直接使用临时文件路径(临时文件会在请求结束后被PHP自动删除)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:01:55