Отправка Formdata с изображением и json на сервер с помощью ajax

#jquery #node.js #ajax #multer #body-parser

#jquery #node.js #ajax #мультер #body-анализатор

Вопрос:

Мне нужно отправить изображение со стороны клиента second ajax вместе с text json first ajax .

На стороне сервера я отправляю изображение в cloudinary (multer) и отправляю сообщение на электронную почту text[0].email с помощью nodemailer. Но при нескольких вызовах ajax я не могу отправить URL-адрес изображения на электронную почту.

html-файл, в котором я получаю значения из входных (first ajax) данных и получаю изображение (second ajax)

 <form id="form_2">
<input type="text" id="company" name="company">
<input type="text" id="name" name="names">
<input type="tel" id="phone" name="phone">
<input type="email" id="email" name="email">
<input type="file" name="image" id="image" accept="image/*">
<input type="submit" class="submit_2" value="Send">
</form>
 

На стороне клиента, где я отправляю изображение и text json на сторону сервера (вызовы ajax)

 $(".submit_2").on("click", function () {
text[0].name = $.trim($("#name").val());
text[0].phone = $.trim($("#phone").val());
text[0].company = $.trim($("#company").val());
text[0].email = $.trim($("#email").val());
text[0].text_in = $.trim($("#text_in").val());

let formdata = new FormData();
formdata.append("image", $("#image")[0].files[0]);

 if ($("#form_2").valid()) {
      $.ajax({  //first ajax
        url: "/bags",
        type: "POST",
        dataType: "json",
        contentType: "application/json",
        data: JSON.stringify(text),
        processData: false,
        crossDomain: true,
      });
      $.ajax({  //second ajax
        url: "/bags",
        type: "POST",
        contentType: false,
        data: formdata,
        processData: false,
        crossDomain: true,
      });
  });
});
 

Сервер

 const express = require("express");

const bodyParser = require("body-parser");
const router = express.Router();
const nodemailer = require("nodemailer");

const cloudinary = require("cloudinary").v2;
const { CloudinaryStorage } = require("multer-storage-cloudinary");
const multer = require("multer");

router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: true }));

cloudinary.config({
  cloud_name: "cloud_namep",
  api_key: "api_key",
  api_secret: "api_secret",
});

const fileFilter = (req, file, cb) => {
  if (
    file.mimetype === "image/png" ||
    file.mimetype === "image/jpg" ||
    file.mimetype === "image/jpeg"
  ) {
    cb(null, true);
  } else {
    cb(null, false);
  }
};

const storage = new CloudinaryStorage({
  cloudinary,
});

const upload = multer({ storage: storage, fileFilter });

let transporter = nodemailer.createTransport({
  host: "host",
  port: 465,
  secure: true, 
  auth: {
    user: "user",
    pass: "pass",
  },
});

router.post("/bags", upload.single("image"), function (req, res, next) {
  console.log(req.body);
  console.log(req.file);
  const email = req.body[0].email,
  const mailData1 = {
    from: {
      name: "sender",
      address: "myemail",
    },
    to: email,
    subject: "text",
    html: "message",  
    attachments: req.file.path,
  };
  transporter.sendMail(mailData, (error, info) => {
    if (error) {
      return console.log(error);
    }
    res.status(200).send({ message: "Mail send", message_id: info.messageId });
  });
  transporter.sendMail(mailData1);
});
 

После нажатия кнопки отправки в консоли у меня есть два сообщения

Консоль

 //first message
[ //req.body
  {
    name: 'sd',
    company: '123',
    phone: '12321312',
    email: '123@mail.ru',
    text_in: '',
  }
]

undefined //req.file

//second message
[Object: null prototype] //req.body

{   //req.file
  fieldname: 'image',
  originalname: 'fdsf.png',
  encoding: '7bit',
  mimetype: 'image/png',
  path: 'https://res.cloudinary.com/dbgqnecjp/image/upload/v1606067372/lfvr9xxarnbegsp2ins7.png',
  size: 3299,
  filename: 'lfvr9xxarnbegsp2ins7'
}
 

Ответ №1:

formdata.append("text", JSON.stringify(text)); на стороне клиента и анализируется req.body.text на сервере. Это работает для меня