Приём файлов AJAX -> PHP

273
24 января 2018, 14:44

Не могу разобраться, при отправке файлов без Ajax - всё норм, при отправке через Ajax - письмо с вложением не отправляется.

$to = 'sergeykozin1@yandex.ru';
if ( isset( $_POST['sendMail'] ) ) {
$post = array(
  'name'   => 'Имя: ', // и т.д. 
);
foreach ($_POST as $key => $value) {
    $body .= ( $post[$key] ? $post[$key] : ($key . ': ') ) . $value . PHP_EOL;
}
if($_FILES)
{
  $filepath = array();
  $filename = array();
  $file2 = array();
  $i = 0;
    foreach ($_FILES["file"]["error"] as $key => $error) {
      if ($error == UPLOAD_ERR_OK) {
        $filename[$i][0] = $_FILES["file"]["tmp_name"][$key];
        $filename[$i][1] = $_FILES["file"]["name"][$key];
        $i++;
      }
    }
  }
  $body .= "Файл:\r\n".$file."\r\n\r\n";
  send_mail($to, $body, $email, $filename);
}

// Вспомогательная функция для отправки почтового сообщения с вложением
function send_mail($to, $body, $email, $filename)
{
  $subject = 'Заказ с сайта ' . $_SERVER['HTTP_HOST'];
  $boundary = "--".md5(uniqid(time())); // генерируем разделитель
  $headers = "From: ". 'vsedlyastudentov.ru' ."\r\n";   
  $headers .= "MIME-Version: 1.0\r\n";
  $headers .="Content-Type: multipart/mixed; boundary=\"".$boundary."\"\r\n";
  $multipart = "--".$boundary."\r\n";
  $multipart .= "Content-type: text/plain; charset=\"utf-8\"\r\n";
  $multipart .= "Content-Transfer-Encoding: quoted-printable\r\n\r\n";
  $body = $body."\r\n\r\n";
  $multipart .= $body;
  foreach ($filename as $key => $value) {
    $fp = fopen($value[0], "r"); 
    $content = fread($fp, filesize($value[0]));
    fclose($fp);
    $file .= "--".$boundary."\r\n";
    $file .= "Content-Type: application/octet-stream\r\n";
    $file .= "Content-Transfer-Encoding: base64\r\n";
    $file .= "Content-Disposition: attachment; filename=\"".$value[1]."\"\r\n\r\n";
    $file .= chunk_split(base64_encode($content))."\r\n";
  }
  $multipart .= $file."--".$boundary."--\r\n";
  mail($to, $subject, $multipart, $headers);
}

$("#file_form").submit(function(e) { 
  e.preventDefault() 
  var $input = $("#file"); 
  var fd = new FormData; 
 
  fd.append('img', $input.prop('files')[0]); 
  $.ajax({ 
      url: 'file.php', 
      data: fd, 
      processData: false, 
      contentType: false, 
      type: 'POST', 
    }) 
    .done(function(html) { 
      //безполезный код 
    }) 
}) 
return false; 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<form action="file.php" method="post" enctype="multipart/form-data" id="file_form"> 
 
  <input type="file" name="file[]" id="file"> 
 
  <input type="submit" value="Узнать стоимость" name="sendMail"> 
</form>

Может кто сталкивался с такой проблемой? Заранее большое спасибо)

Answer 1

Вобщем нагуглил рабочий ответ здесь

// этот участок кода нужен только для отображения гифки 
// которая даёт пользователю понять, что что-то происходит 
// и нужно подождать 
$(document).ready(function() { 
  $(document).ajaxStart(function() { 
    // найдем элемент с изображением загрузки и уберем невидимость: 
    var imgObj = $("#load-indicator"); 
    imgObj.show(); 
    // вычислим в какие координаты нужно поместить изображение загрузки, 
    // чтобы оно оказалось в серидине страницы: 
    var centerY = $(window).scrollTop() + ($(window).height() + imgObj.height()) / 2; 
    var centerX = $(window).scrollLeft() + ($(window).width() + imgObj.width()) / 2; 
    imgObj.offset({ 
      left: centerX, 
      top: centerY 
    }); 
  }); 
  //скрываем изображение после окончания AJAX-запроса 
  $(document).ajaxStop(function() { 
    $('#load-indicator').hide(); 
  }); 
}); 
 
// назначаем действие на такое событие как отправка формы 
$('#feedback').submit(function(evtObj) { 
  evtObj.preventDefault(); 
  // Если элемент формы fileforsending содержит значения (т.е. выбран файл для отправки), 
  // то вместо AJAX-запроса используем FormData() 
  // поскольку файлы через AJAX-запросы не передаются                 
 
  if (document.getElementById("feedback").fileforsending.value !== '') { 
    //показываем гифку ожидания 
    var imgObj = $("#load-indicator"); 
    imgObj.show(); 
    var centerY = $(window).scrollTop() + ($(window).height() + imgObj.height()) / 2; 
    var centerX = $(window).scrollLeft() + ($(window).width() + imgObj.width()) / 2; 
    imgObj.offset({ 
      left: centerX, 
      top: centerY 
    }); 
    // этот кусок кода я спёр отсюда http://javascript.ru/forum/jquery/40698-ajax-i-otpravka-fajjlov-s-formy.html 
    var form = document.forms.feedback; 
    var formData = new FormData(form); 
    var xhr = new XMLHttpRequest(); 
    xhr.open("POST", "mails_sender.php"); 
    xhr.onreadystatechange = function() { 
      if (xhr.readyState == 4) { 
        if (xhr.status == 200) { 
          data = xhr.responseText; 
          $("#result").html('Результат выполнения: ' + data); 
          // Письмо отправлено, сбрасываем данные формы если прошло успешно 
          if (data === 'Отправлено письмо с вложениями.') { 
            document.getElementById("feedback").reset(); 
          } 
          //убираем гифку ожидания 
          $('#load-indicator').hide(); 
        } 
      } 
    }; 
    xhr.send(formData); 
    // В противном случае (не прикреплён файл для отправки) 
    // Делаем AJAX-запрос для отправки письма 
  } else { 
    var form = $(this); 
    $.ajax({ 
      // Здесь файл, который обрабатывает полученные от пользователя данные и отправляет почту 
      url: 'mails_sender.php', 
      type: 'POST', 
      data: form.serialize(), 
      // Действия в случае успешной отправки AJAX-запроса (а не письма!) 
      // Здесь data - полученное от mails_sender.php сообщение 
      success: function(data) { 
        if (data === 'Отправлено письмо без вложений.') { 
          $("#result").html('Отправлено письмо без вложений.'); 
          // Письмо отправлено, сбрасываем данные формы 
          document.getElementById("feedback").reset(); 
          // Следующая строка после успешной отправки сообщения 
          // перенаправляет пользователь на любую страницу/сайт 
          // достаточно раскомментировать её и поменять адрес сайта codeby.net 
          // на ваш собственный 
          //document.location.href = 'https://codeby.net'; 
        } else { 
          $("#result").html(data); 
        } 
      }, 
      error: function(data) { 
        $("#result").html('Результат выполнения: ' + data); 
      } 
    }); 
  } 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<form method="post" action="mails_sender.php" id="feedback" name="feedback" enctype="multipart/form-data"> 
  <table style="width: 100%"> 
    <tr> 
      <td style="width: 146px">Ваш e-mail</td> 
      <td><input name="youremail" type="text" style="width: 440px" size="20" /></td> 
    </tr> 
    <tr> 
      <td style="width: 146px">Тема сообщения</td> 
      <td><input name="subject" type="text" style="width: 440px" size="20" /></td> 
    </tr> 
    <tr> 
      <td>Опции для выбора:</td> 
      <td> 
        <select name="option" style="width: 440px"> 
                            <option style='color:#CCCCCC;'>- - Выберите из списка - -</option> 
                            <option value="Опция 1">Опция 1</option> 
                            <option value="Опция 1">Опция 2</option> 
                            <option value="Опция 1">Опция 3</option> 
                        </select></td> 
    </tr> 
    <tr> 
      <td style="width: 146px">Ваше сообщение</td> 
      <td> 
        <textarea name="message" style="width: 440px; height: 130px" rows="1" cols="20"></textarea></td> 
    </tr> 
    <tr> 
      <td style="width: 146px">Ваше имя</td> 
      <td><input name="name" type="text" style="width: 440px" size="20" value="" /></td> 
    </tr> 
 
    <tr> 
      <td style="width: 146px">Вы можете присоединить необходимые файлы</td> 
      <td><input name="fileforsending" type="file" style="width: 440px" /></td> 
    </tr> 
    <tr> 
      <td style="width: 146px">&nbsp;</td> 
      <td><br /> 
        <input name="Reset1" type="reset" value="Очистить" style="width: 97px" /> 
        <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
                            <input name="Submit1" type="submit" value="Отправить" style="width: 157px" /> 
                            &nbsp; </span> 
      </td> 
    </tr> 
  </table> 
</form> 
 
<div style="color: red;" id="result"></div><br /> 
<img src="ajax-loader.gif" id="load-indicator" alt="loading" style="position:absolute; z-index:1000; display:none;" />

<?php 
  
// Адрес, куда отправляем письмо 
$to = 'mial@localhost'; 
  
// Получаем данные от пользователя 
// Все данные обязательно нужно проверять на правильность! 
$userEmail = filter_input(INPUT_POST, 'youremail', FILTER_VALIDATE_EMAIL); 
$subject = filter_input(INPUT_POST, 'subject', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); 
$option = filter_input(INPUT_POST, 'option', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); 
$message = strip_tags(filter_input(INPUT_POST, 'message', FILTER_SANITIZE_MAGIC_QUOTES), '<p><a><b><div>'); 
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); 
  
// Проверка, что данные не пустые.  
// Нас не интересуют анонимки 
if (empty($userEmail)) { 
    die('Отсутствует или неверен адрес почты.'); 
// Нас не интересуют послания с пустым сообщением 
} elseif (empty($message)) { 
    die('Отсутствует сообщение.'); 
} elseif (empty($subject)) { 
    $subject = '[тема не указана]'; 
} 
  
$the_file = ''; 
//Если пользователь выбрал файл для отправки 
if (!empty($_FILES['fileforsending']['tmp_name'])) { 
    // Закачиваем файл 
    $path = $_FILES['fileforsending']['name']; 
    if (copy($_FILES['fileforsending']['tmp_name'], $path)) { 
        $the_file = $path; 
    } 
} 
// Если есть прикреплённый файл, то заголовки чуть другие. 
// Поэтому, в зависимости от того, отправил ли пользователь файл, 
// выбираем, что делать дальше 
$headers = null; 
  
if (empty($the_file)) { 
    // эта часть кода отвечает за отправку сообщений без вложений 
    // собираем заголовки 
    $headers = array(); 
    $headers[] = "MIME-Version: 1.0"; 
    $headers[] = "Content-type: text/html; charset=UTF-8"; 
    $headers[] = "From: $name <$userEmail>"; 
    $headers[] = "Bcc: JJ Chong <bcc@domain2.com>"; 
    $headers[] = "Reply-To: Recipient Name <receiver@domain3.com>"; 
    $headers[] = "Subject: {$subject}"; 
    $headers[] = "X-Mailer: PHP/" . phpversion(); 
    // собираем текст письма 
    $allmsg = "<p><b>E-mail:</b> $userEmail</p> 
        <p><b>Выбранная опция:</b> $option</p> 
            <p><b>Сообщение:</b> $message</p>"; 
    $allmsg = "<html><head><title>Обратная связь</title><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"></head><body>" . $allmsg . "</body></html>"; 
    // отправляем 
    if (!mail($to, $subject, $allmsg, implode("rn", $headers))) { 
        echo 'Письмо не отправлено - что-то не сработало.'; 
    } else { 
        echo 'Отправлено письмо без вложений.'; 
    } 
} else { 
    // эта часть кода отвечает за отправку сообщений с вложениями 
    // читаем отправляемый файл в строку 
    $fp = fopen($the_file, "r"); 
    if (!$the_file) { 
        die("Ошибка отправка письма: Файл $the_file не может быть прочитан."); 
    } 
    $file = fread($fp, filesize($path)); 
    fclose($fp); 
    // удаляем временный файл 
    unlink($path); 
    // собираем текст письма 
    $allmsg = "<p><b>E-mail:</b> $userEmail</p> 
        <p><b>Выбранная опция:</b> $option</p> 
            <p><b>Сообщение:</b> $message</p>"; 
    $allmsg = "<html><head><title>Обратная связь</title><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"></head><body>" . $allmsg . "</body></html>"; 
    // генерируем разделитель 
    $boundary = "--" . md5(uniqid(time())); 
    // собираем заголовки 
    $headers = array(); 
    $headers[] = "MIME-Version: 1.0"; 
    $headers[] = "From: $name <$userEmail>"; 
    $headers[] = "Bcc: JJ Chong <bcc@domain2.com>"; 
    $headers[] = "Reply-To: Recipient Name <receiver@domain3.com>"; 
    $headers[] = "Subject: {$subject}"; 
    $headers[] = "X-Mailer: PHP/" . phpversion(); 
    $headers[] = "Content-Type: multipart/mixed; boundary="$boundary"n"; 
    // собираем текст письма + приложенынй файл 
    $multipart = array(); 
    $multipart[] = "--$boundary"; 
    $multipart[] = "Content-Type: text/html; charset=UTF-8"; 
    $multipart[] = "Content-Transfer-Encoding: Quot-Printedrn"; 
    $multipart[] = "$allmsgrn"; 
    $multipart[] = "--$boundary"; 
    $multipart[] = "Content-Type: application/octet-stream"; 
    $multipart[] = "Content-Transfer-Encoding: base64"; 
    $multipart[] = "Content-Disposition: attachment; filename = "" . $path . ""rn"; 
    $multipart[] = chunk_split(base64_encode($file)); 
    $multipart[] = "--$boundary"; 
    // отправляем 
    if (!mail($to, $subject, implode("rn", $multipart), implode("rn", $headers))) { 
        echo 'Письмо не отправлено - что-то не сработало.'; 
    } else { 
        echo 'Отправлено письмо с вложениями.'; 
    } 
} 
 
$userEmail = filter_input(INPUT_POST, 'youremail', FILTER_VALIDATE_EMAIL); 
$subject = filter_input(INPUT_POST, 'subject', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); 
$option = filter_input(INPUT_POST, 'option', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); 
$message = strip_tags(filter_input(INPUT_POST, 'message', FILTER_SANITIZE_MAGIC_QUOTES), '<p><a><b><div>'); 
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);

READ ALSO
Поставить балун для каждого маршрута и отцентрировать карту относительно нескольких маршрутов яндекс карты(API 2.1)

Поставить балун для каждого маршрута и отцентрировать карту относительно нескольких маршрутов яндекс карты(API 2.1)

Есть карта, с несколькими маршрутами, как поставить балун для каждого маршрута, чтоб по нажатию на маршрут он открывался, и как отцентрировать...

315
Git работа с локальными файлами [требует правки]

Git работа с локальными файлами [требует правки]

Создал на рабочем столе папку с файлом, зашел в нее, открыл git bash, пишу git status и мне выбивает untracked файлы которые находятся на рабочем столе,...

198