Отправка письма с вложениями на PHP и AJAX

Отправка письма с вложениями на PHP и AJAX

2 марта 2020 PHP

Мы уже рассматривали, как сделать форму обратной связи на PHP и Ajax. Сегодня мы модернизируем её и научим отправлять приложенные файлы.

HTML-код формы

Добавляем в форму ещё одно поле файл:

<form id="feedback-form" action="">
	<input type="text" name="name" required placeholder="Ваше имя">
	<input type="tel" name="phone" required placeholder="Ваш телефон">
	<textarea name="text" placeholder="Ваш текст"></textarea>
	<input type="file" name="file" required />
	<input type="submit" name="submit" value="Отправить">
</form>

JavaScript код с jQuery Ajax

Не забудьте перед кодом подключить библиотеку jQuery!

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

Отправляем данные с помощью объекта FormData — предназначенного для кодирования данных, которые необходимо отправить на сервер посредством технологии AJAX (XmlHttpRequest). Для кодирования данных метод FormData использует формат multipart/form-data. Это означает то, что можно подготовить для отправки по AJAX не только текстовые данные, но и файлы (input с атрибутом type="file").

<script>
$(document).ready(function () {
    $("form").submit(function () {
    // Получение ID формы
    var formID = $(this).attr('id');
    // Добавление решётки к имени ID
    var formNm = $('#' + formID);
    $.ajax({
      type: "POST",
      url: '/send.php',
      data: new FormData(formNm),
	  processData: false,
	  contentType: false,

      beforeSend: function () {
        // Вывод текста в процессе отправки
        $(formNm).html('<p style="text-align:center">Отправка...</p>');
      },
      success: function (data) {
        // Вывод текста результата отправки
        $(formNm).html('<p style="text-align:center">'+data+'</p>');
      },
      error: function (jqXHR, text, error) {
        // Вывод текста ошибки отправки
        $(formNm).html(error);
      }
    });
    return false;
  });
});
</script>

PHP обработчик

Файлы, которые будут отправлены, необходимо закодировать в формат base64 и указать в заголовках информацию о том, что в письме присутствуют файлы.

Чтобы отделить закодированный файл от текста письма, необходимо добавить текстовый разделитель, это может быть любая уникальная строка, в нашем случае $boundary = "---";. Разделитель следует обозначить в отправляемых заголовках, и выводить до и после прикрепления файла в тексте письма.

eco-service.kz

<?
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' && !empty($_POST['name'])) {
    $message = 'Имя: ' . $_POST['name'] . ' ';
    $message .= 'Телефон: ' . $_POST['phone'] . ' ';
	if(!empty($_POST['text'])) {
		$message = 'Текст: ' . $_POST['text'] . ' ';
	}
	
	$mailTo = "mail@mail.ru"; // Ваш e-mail
	$subject = "Письмо с сайта"; // Тема сообщения
	$from = "info@site.ru"; // Почта отправителя
	
	$boundary = "---"; //Разделитель
	/* Заголовки */
	$headers = "From: $from\nReply-To: $from\n";
	$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"";
	$body = "--$boundary\n";
	/* Присоединяем текстовое сообщение */
	$body .= "Content-type: text/html; charset='utf-8'\n";
	$body .= "Content-Transfer-Encoding: quoted-printablenn";
	$body .= "Content-Disposition: attachment; filename==?utf-8?B?".base64_encode($filename)."?=\n\n";
	$body .= $message."\n";
	$body .= "--$boundary\n";
	
	if ($_FILES['file']['error'] == UPLOAD_ERR_OK) {
		// получаем расширение исходного файла
		$ext = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
		// получаем уникальное имя под которым будет сохранён файл 
		$filename = md5(uniqid('', true)).'.'.$ext;
		// перемещаем файл из временного хранилища в указанную директорию
		if (move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$filename)) {
			
			$file = fopen($filename, "r"); //Открываем файл
			$text = fread($file, filesize($filename)); //Считываем весь файл
			fclose($file); //Закрываем файл
			
		}
	}
	
	/* Добавляем тип содержимого, кодируем текст файла и добавляем в тело письма */
	$body .= "Content-Type: application/octet-stream; name==?utf-8?B?".base64_encode($filename)."?=\n";
	$body .= "Content-Transfer-Encoding: base64\n";
	$body .= "Content-Disposition: attachment; filename==?utf-8?B?".base64_encode($filename)."?=\n\n";
	$body .= chunk_split(base64_encode($text))."\n";
	$body .= "--".$boundary ."--\n";
	
    if(mail($mailTo, $subject, $body, $headers)) {
        echo "Спасибо! Мы свяжемся с вами в самое ближайшее время!"; 
    } else {
        echo "Сообщение не отправлено!"; 
    }
}
?>
Если вам понравилась статья, вы можете отблагодарить автора любой суммой, какую сочтете для себя приемлемой:
Остались вопросы по статье? Задайте их прямо сейчас!
Похожие записи
Как запретить переход по ссылке и отменить действия по умолчанию на JavaScript

Если мы используем JavaScript, то некоторые действия по умолчанию нужно отменить. Самый распространённый случай это клик по ссылке. К примеру при нажатии должно появляться всплывающее окно, но по умолчанию браузер будет переходить по URL. Если в атрибуте href указать знак Читать далее

Автоопределение города по IP на сайте

Необходимость определить город посетителя на сайте актуально для интернет-магазинов или сайтов работающих в разных регионах. Это даст возможность показывать разные контакты, и изменять текст на страницах в зависимости от текущего местоположения пользователя. Самый простой и эффективный способ - это определить Читать далее

Подключение jQuery

jQuery - это быстрая, небольшая и многофункциональная библиотека JavaScript, включенная в один файл .js. На данный момент это самая популярная библиотека JavaScript. JQuery облегчает жизнь веб-разработчика. Библиотека предоставляет множество встроенных функций, с помощью которых вы можете легко и быстро выполнять Читать далее

Живой поиск jQuery

Сегодня я расскажу об одном отличном jQuery плагине о котором вы могли не знать. С его помощью можно быстро сделать живой поиск на странице сайта с множеством элементов. Называется он HideSeek. Плагин очень прост в использовании, но в то же Читать далее

Сохранение данных в форме после обновления страницы

Часто ли у вас случалось такое, что при заполнении формы на сайте истекал срок действия сеанса или например зависал браузер, после чего приходилось заполнять форму заново?! HTML5 представил концепцию механизмов хранения заполняемых данных в браузере. В хранилище HTML5 есть возможность Читать далее

Кастомный виджет переводчик для сайта с флагами

Сегодня мы кастомизируем стандартный виджет Google переводчика для сайта и сделаем его в виде меню с флагами. На данный момент сервис Google Translate Widget больше не поддерживается, но это никак не отразится на сайтах, которые были подключены ранее. Наш кастомный Читать далее

AJAX в 1C-Битрикс

В компонентах Битрикс есть встроенный функционал для AJAX подгрузки. Его так же можно использовать, например для бесконечного скролла новостей. Но есть и более простой способ, с помощью которого можно загружать ответ любого компонента без перезагрузки страницы. Его мы и рассмотрим Читать далее

2 комментария на «Отправка письма с вложениями на PHP и AJAX»

  1. Иван:

    Код свой посмотри.
    Как он у тебя работать будет???
    Писака…

  2. Александр:

    Ты зачем в FormData объект jquery передаешь, бестолочь?

Добавить комментарий

*

code