Подскажите, как сюда прикрутить ajax?
Здравствуйте. После двухнедельного искания формы с отправкой нескольких файлов на почту без перезагрузки, я её всё таки нашел. Но вот осталась одна проблема, как сюда добавить ajax? Посмотрите пожалуйста на код:
<form enctype="multipart/form-data" method="post" id="feedback-form"> <label for="nameFF">Имя:</label> <input type="text" name="nameFF" id="nameFF" required placeholder="например, Иван Иванович Иванов" x-autocompletetype="name" class="w100 border"> <label for="contactFF">Email:</label> <input type="email" name="contactFF" id="contactFF" required placeholder="например, ivan@yandex.ru" x-autocompletetype="email" class="w100 border"> <label for="fileFF">Прикрепить файл:</label> <input type="file" name="fileFF[]" multiple id="fileFF" class="w100"> <label for="messageFF">Сообщение:</label> <textarea name="messageFF" id="messageFF" required rows="5" placeholder="Детали заявки…" class="w100 border"></textarea> <br> <input value="Отправить" type="submit" id="submitFF"> </form> document.getElementById('feedback-form').addEventListener('submit', function(evt){ var http = new XMLHttpRequest(), f = this; evt.preventDefault(); http.open("POST", "contacts.php", true); http.onreadystatechange = function() { if (http.readyState == 4 && http.status == 200) { alert(httfp.responseText); if (http.responseText.indexOf(f.nameFF.value) == 0) { // очистить поле сообщения, если в ответе первым словом будет имя отправителя f.messageFF.removeAttribute('value'); f.messageFF.value=''; } } } http.onerror = function() { alert('Извините, данные не были переданы'); } http.send(new FormData(f)); }, false); <?php if (isset ($_POST['contactFF'])) { $to = "@gmail.com"; // поменять на свой электронный адрес $from = $_POST['contactFF']; $subject = "Заполнена контактная форма с ".$_SERVER['HTTP_REFERER']; $message = "Имя: ".$_POST['nameFF']."\nEmail: ".$from."\nIP: ".$_SERVER['REMOTE_ADDR']."\nСообщение: ".$_POST['messageFF']; $boundary = md5(date('r', time())); $filesize = ''; $headers = "MIME-Version: 1.0\r\n"; $headers .= "From: " . $from . "\r\n"; $headers .= "Reply-To: " . $from . "\r\n"; $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n"; $message=" Content-Type: multipart/mixed; boundary=\"$boundary\" --$boundary Content-Type: text/plain; charset=\"utf-8\" Content-Transfer-Encoding: 7bit $message"; for($i=0;$i<count($_FILES['fileFF']['name']);$i++) { if(is_uploaded_file($_FILES['fileFF']['tmp_name'][$i])) { $attachment = chunk_split(base64_encode(file_get_contents($_FILES['fileFF']['tmp_name'][$i]))); $filename = $_FILES['fileFF']['name'][$i]; $filetype = $_FILES['fileFF']['type'][$i]; $filesize += $_FILES['fileFF']['size'][$i]; $message.=" --$boundary Content-Type: \"$filetype\"; name=\"$filename\" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=\"$filename\" $attachment"; } } $message.=" --$boundary--"; if ($filesize < 10000000) { // проверка на общий размер всех файлов. Многие почтовые сервисы не принимают вложения больше 10 МБ mail($to, $subject, $message, $headers); echo $_POST['nameFF'].', Ваше сообщение получено, спасибо!'; } else { echo 'Извините, письмо не отправлено. Размер всех файлов превышает 10 МБ.'; } } ?> Я знаю, что по средствам ajax можно сделать то что я хочу, но увы знаний у меня не хватает... В конце я хочу получить такой вид: человек нажимает на кнопку "отправить" и появляется анимация загрузки и потом выводится результат. либо положительный, либо отрицательный. Пока что есть такой код. $("#feedback-form").submit(function() { var str = $(this).serialize(); $.ajax({ type: "POST", url: "contacts.php", data: str, success: function(msg) { if(msg == 'ok') { $(".result").toggleClass("dis"); return false; } else { $(".notresult").toggleClass("dis"); return false; } } }); return false; }); Но он, как вы понимаете, не получает msg == 'ok' . Письма уходят, но только почему то без файлов... Подскажите, как ему передать msg == 'ok' и не терять функцию отправки файлов? P.S. Еще остаётся вопрос, как добавить анимацию загрузки? В какую строчку его засунуть ? |
var http = new XMLHttpRequest().... это и есть Ajax, чего еще добавлять, кроме как обработку ответов сервера.
$subject = "Заполнена контактная форма с ".$_SERVER['HTTP_REFERER']; - так нельзя отправлять тему сообщения, ее нужно кодировать. И принимать так файлы тоже нельзя - нужно уже на клиенте знать параметры сервера, которые накладывают ограничения на загрузку файлов. |
1) ajax - это jquery, а текущий код работает без jquery. Тогда выходит, что var http = new XMLHttpRequest().... не ajax...
2)если было бы нельзя, то ничего бы не работало... Но всё работает. Всё перестаёт работать, когда я пытаюсь прикрутить ajax) |
Цитата:
Цитата:
Вы так лихо file_get_contents($_FILES['fileFF']['tmp_name'][$i]), даже не проверяя загружено ли изображение.... и это по вашему работа? Работать с файлами нужно только после проверки ключа "error" на отсутствие ошибок. Сервер накладывает ограничения на загрузку файлов - на макс. размер файла, на количество файлов и общий размер $_POST данных. Кроме этого любой уважающий себя хост всегда следит за 25 портом и отправлять почту любого размера не позволит. Работает у вас так, на халяву, пока не гикнут вас с вашим подходом к написания скриптов, и получите вы по шапке. Тогда может задумаетесь как должно работать. |
Цитата:
Цитата:
Вы так отвечает будто там, в решении моего вопроса, много строк кода... Прошу знающих людей помочь мне в этом простом для вас, и в сложном для меня деле. |
Цитата:
Первым делом, это нужно в панели управления узнать разрешения на почту, обычно это ограничения на количество сообщений отправляемых за единицу времени и на размер почтового отправлений. Из этого размера и нужно исходить, то есть еще на клиенте проверять размер загружаемых файлов, и по приему формы сервером опять проверять, и обязательно! Сам сервер накладывает ограничения на загрузку файлов, которые тоже можно узнать в панели. Если панель не дает об этом полной информации, то это можно получить таким образом: //макс. размер POST данных в МБ, //этот размер должен превышать весь объем данных формы, включая и файлы ini_get('post_max_size')+0; //макс. размер загружаемого файла МБ ini_get('upload_max_filesize')+0; //количество загружаемых файлов, контролируется начиная с версии 5.2.12 ini_get('max_file_uploads'); Эти параметры также нужно передать на клиента, проверяя по ним загрузку файлов. На сервере, тем более отправляя почту, нужно не "Это уже другой вопрос", а первостепенный вопрос, ибо вы не проверяя загружено или нет, плюхаете на почту, не проверяя ошибок, а нужно отправлять только в том случае, если их нет. Если они есть, то об этом должен знать клиент и причину ошибки. А для того чтобы не хвататься сразу за формирование сообщения, а проверить отсутствие ошибок загрузки, достаточно получить ключи массива $_FILES['error'] отличные от ноля: if(!$e = array_diff($_FILES['fileFF']['error'], array(0))) { if(!$size = array_sum(array_column($_FILES['fileFF'], 'size')) < $sizemail) { //нет ошибок загрузки, формируем сообщение //загружая файлы с проверкой is_uploaded_file } //иначе сообщаем клиенту - низзя } //иначе $e содержит массив ошибок, сообщаем клиенту //функция array_column() доступна начиная с версии 5.5.0 //если версия ниже, функцию можно заменить пользовательской function arrayColumn($a, $i) { return array_values(array_diff(array_map(function($v) use($i) { return $v[$i]; }, $a), array(null))); } //имена файлов всегда нужно обрабатывать как: $filename = basename($_FILES['fileFF']['name']); //пусть для письма как текст это и не страшно //просто это должно стать привычкой На клиенте эти параметры можно проверить получая соответствующие свойства массива files поля file. Как это делается и на этом форуме не раз приводилось, да и в сети об этом полно. Тему почтового сообщения кодируют: $subject ='=?utf-8?b?' . base64_encode('Заполнена контактная форма с '.$_SERVER['HTTP_REFERER']) . '?='; //тоже самое делать и с данными для поля From, если к адресу добавляют текст $headers = 'From: =?utf-8?B?' . base64_encode($data) . '?= <' .$email. '>' . PHP_EOL; |
1)Поменял
$filename = $_FILES['fileFF']['name'][$i]; на $filename = basename($_FILES['fileFF']['name']); и получил вот такое сообщение диалоговом окне: <br /> <b> Warning</b>: basename () expects parameter 1 to be string array given in <b>F:\openserver\......\contacts.php</b> on line <b>26</b> <br /> mymail@123.ru. Ваше сообщение получено спасибо! А на почту пришел файл noname... Открыть его нельзя. $filename = basename($_FILES['fileFF']['name']); - только усложняет жизнь. 2)С этим строчками вообще не разобрался. if(!$e = array_diff($_FILES['fileFF']['error'], array(0))) { if(array_sum(array_column($_FILES['fileFF'], 'size')) < $sizemail) { //нет ошибок загрузки, формируем сообщение //загружая файлы с проверкой is_uploaded_file } //иначе сообщаем клиенту - низзя } //иначе $e содержит массив ошибок, сообщаем клиенту //функция array_column() доступна начиная с версии 5.5.0 //если версия ниже, функцию можно заменить пользовательской function arrayColumn($a, $i) { return array_values(array_diff(array_map(function($v) use($i) { return $v[$i]; }, $a), array(null))); } я так понимаю, я должен был получить, что то типа этого if(!$e = array_diff($_FILES['fileFF']['error'], array(0))) { if(array_sum(array_column($_FILES['fileFF'], 'size')) < $sizemail) { for($i=0;$i<count($_FILES['fileFF']['name']);$i++) { if(is_uploaded_file($_FILES['fileFF']['tmp_name'][$i])) { $attachment = chunk_split(base64_encode(file_get_contents($_FILES['fileFF']['tmp_name'][$i]))); $filename = $_FILES['fileFF']['name'][$i]; $filetype = $_FILES['fileFF']['type'][$i]; $filesize += $_FILES['fileFF']['size'][$i]; $message.=" --$boundary Content-Type: \"$filetype\"; name=\"$filename\" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=\"$filename\" $attachment"; } } function arrayColumn($a, $i) { return array_values(array_diff(array_map(function($v) use($i) { return $v[$i]; }, $a), array(null))); } Но на выходе я получал: <br /> <b> Parse error</b>: syntax error, unexpected $end in <b>f:\openserver\...\contacts.php</b> on line <b>56</b> <br /> Кстати на 56 линии находится ?> и что за $end, я понятия не имею... |
Я же просто пишу пример, для единичного файла, а вы загружаете массив файлов, поэтому надо:
$filename = basename($_FILES['fileFF']['name'][$i]); В сети ищите темы типа "как правильно загружать файлы" и подобное, там прочтете для чего это делается. Эта функция не усложняет, а помогает, просто не знаете вы языка, если копируете, а не понимаете. Ошибка "syntax error, unexpected $end" гласит о том, что не закрыта конструкция, то есть, нет или лишняя фигурная скобка. Вы просто вырвали кусок кода из примера и вставили его себе, и конечно у вас нет закрывающих скобок, поэтому и ошибка. Должно быть так: if(!$e = array_diff($_FILES['fileFF']['error'], array(0))) { if(($size = array_sum(array_column($_FILES['fileFF'], 'size'))) < $sizemail) { //формирование почтового отправления, то есть //$to = "@gmail.com"; // поменять на свой электронный адрес //$from = $_POST['contactFF']; //и так далее for($i=0;$i<count($_FILES['fileFF']['name']);$i++) { if(is_uploaded_file($_FILES['fileFF']['tmp_name'][$i])) { //добавление файлов к почте, то есть заполнение $attachment и т.д. } else { //подстава - файл левый, прекращаем работу скрипта exit('Да и идите вы ...'); } } } else { //формируем информацию о превышении размера файлов разрешенных для загруки //то есть если их размер превышает размер $sizemail разрешенный для отправкой почтой //$size - содержит размер всех загруженных файлов } } else { //формируем информацию об ошибках загрузки файлов для пользователя //ключи массива $e будут указывать на файлы загруженные с ошибками } А пользовательская функция arrayColumn() нужна только в том случае, если у вас версия РНР ниже 5.5.0 (ориентироваться надо не на локальный сервер, а реальный, тот что будет, устанавливая на локальном такую же версию, в Open Server это сделать легко), то есть так: arrayColumn($_FILES['fileFF'], 'size') вместо array_column($_FILES['fileFF'], 'size') при этом поместить ее не в этот скрипт отправки почты, а в подключаемый файл пользовательских функций, она не раз пригодится еще, о ее назначении тут. Иначе эта функция не нужна, и нужно использовать стандартную array_column(). |
Спасибо вам за помощь, но вы можете просто сказать, что нужно в ajax jquery изменить, чтобы он отправлял файлы?
$("#feedback-form").submit(function() { var str = $(this).serialize(); $.ajax({ type: "POST", url: "contacts.php", data: str, success: function(msg) { if(msg == 'ok') { $(".result").toggleClass("dis"); return false; } else { $(".notresult").toggleClass("dis"); return false; } } }); return false; }); |
Я уже сказал - у вас есть в коде отправка именно Ajax методом - вот непосредственно строка отправки формы http.send(new FormData(f));, прикручивать сюда еще $.ajax jQuery совсем не нужно.
Только нужно добавить проверку на условия, не отправлять форму пока условия не будут соблюдены, а также возвращать ошибки при проверке формы на сервере. В общем нужно добавить диалог-клиент сервер. Ведь не только загрузку файлов проверять надо на сервере, но и заполнение полей необходимых, если они обязательные для заполнения. |
Часовой пояс GMT +3, время: 08:58. |