Это результат объединения статей:
* форма не работает намеренно, присутствует для того, чтобы можно было оценить внешний вид, пощёлкав по кнопкам.Особенности:
- Внешний вид:
- форма по прежнему резиновая, но теперь наименования пунктов располагаются слева (см. свойство float),
- при нажатии на label фокус получает соответствующий input,
- при наведении курсора мышки на поле, его границы становятся голубыми, при фокусе — бледно-голубыми,
- правильно заполненные поля будут темнеть.
- Поддержка от IE10 включительно.
- Проверка на правильность заполнения полей осуществляется не на стороне сервера.
Ниже представлены два варианта скрипта отправки данных с сайта на почту: с Javascript (Ajax) и без.
1. Форма связи позволяет отправить несколько изображений и др.файлов без перезагрузки страницы
- PHP вынесен в отдельный файл
- при нажатии клавиши F5 форма не будет отправлена снова
- после отправки формы страница не будет перезагружена
Файл contacts.html
<!DOCTYPE HTML> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Контактная форма</title> <style> #feedback-form { /* вся форма */ max-width: 550px; padding: 2%; border-radius: 3px; background: #f1f1f1; } #feedback-form label { /* наименование полей */ float: left; display: block; clear: right; } #feedback-form .w100 { /* поля */ float: right; max-width: 400px; width: 97%; margin-bottom: 1em; padding: 1.5%; } #feedback-form .border { /* граница полей */ border-radius: 1px; border-width: 1px; border-style: solid; border-color: #C0C0C0 #D9D9D9 #D9D9D9; box-shadow: 0 1px 1px rgba(255,255,255,.5), 0 1px 1px rgba(0,0,0,.1) inset; } #feedback-form .border:focus { outline: none; border-color: #abd9f1 #bfe3f7 #bfe3f7; } #feedback-form .border:hover { border-color: #7eb4ea #97cdea #97cdea; } #feedback-form .border:focus::-moz-placeholder { /* убрать при фокусе первоначальный текст поля */ color: transparent; } #feedback-form .border:focus::-webkit-input-placeholder { color: transparent; } #feedback-form .border:not(:focus):not(:hover):valid { /* правильно заполненные поля */ opacity: .8; } #submitFF { /* кнопка "Отправить" */ padding: 2%; border: none; border-radius: 3px; box-shadow: 0 0 0 1px rgba(0,0,0,.2) inset; background: #669acc; color: #fff; } #feedback-form br { height: 0; clear: both; } #submitFF:hover { background: #5c90c2; } #submitFF:focus { box-shadow: 0 1px 1px #fff, inset 0 1px 2px rgba(0,0,0,.8), inset 0 -1px 0 rgba(0,0,0,.05); } </style> <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> <script> 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(http.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); </script>
Файл contacts.php
<?php if (isset ($_POST['contactFF'])) { $to = "name@yandex.ru"; // поменять на свой электронный адрес $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 МБ.'; } } ?>
2. Форма связи в одном файле
Рекомендации к скрипту отправки файлов на почту
- нужно заменить свой@yandex.ru
- нужно заменить contacts.php на полный адрес, например, http://сайт.ru/папка/папка/contacts.php
- серые заголовки лучше убрать. Они меняют адрес хостинга на тот, что посетитель указывает в форме. Но некоторые почтовые сервисы (например, Яндекс.Почта) при их наличии не присылают письма вовсе
- для того, чтобы добавить новое поле, нужно внести изменение в HTML и PHP код. Другими словами, добавить те же участки, что и для messageFF
- для того, чтобы настроить прикрепление только одного файла, следует убрать всё выделенное. По умолчанию прикреплять можно несколько файлов
- для того, чтобы можно было прикреплять только определённый тип файлов, в input прописывается атрибут accept. По умолчанию неважно что прикреплять: картинки, видео или документы
<input type="file" name="fileFF[]" multiple id="fileFF" class="w100" accept="image/*">
Скорее всего письма будут падать в СПАМ папку, поэтому для них нужно создать правило. Скажем, так это делается в Яндекс.Почте:
Если на хостингах выключена функция mail() (галка может именоваться "sendmail_from"), то скрпт работать не будет. Так как по факту email отправляется с электронного ящика хостинга.
127 комментариев:
Спасибо заранее =)
Желательно чтоб было реализовано все на столько же просто как данная форма. Т.к. я не просто ноль, а ноль с большим минусом. И мои знания ограничиваются копировал-вставил.
http://habrahabr.ru/post/120370/
http://www.emanueleferonato.com/2008/07/22/sending-email-with-multiple-attachments-with-php/
http://www.w3schools.com/html/html5_draganddrop.asp
Или посмотрите тут http://shpargalkablog.ru/2013/08/bell-site.html
php практически везде одинаковый, работает благодаря функции mail
???????
"Warning: file_get_contents() [function.file-get-contents]: Filename cannot be empty in.........
Warning: Cannot modify header information - headers already sent by (output started at........"
Как разрешить отправлять без прикрепленного файла?
Спасибо
<?php
if (isset ($_POST['contactFF'])) {
$output = '<p style="color: green">Ваше сообщение получено, спасибо!</p>';
$to = $_POST['mycontactFF'];
$from = $_POST['contactFF'];
$subject = "Заполнена контактная форма с ".$_SERVER['HTTP_REFERER'];
$message = "Имя: ".$_POST['nameFF']."\nEmail: ".$from."\nСообщение: ".$_POST['messageFF'];
$headers = "From: " . $from . "\r\n";
$headers .= "Reply-To: " . $from . "\r\n";
if (isset($_FILES['fileFF']['tmp_name'])) {
$attachment = chunk_split(base64_encode(file_get_contents($_FILES['fileFF']['tmp_name'])));
$filename = $_FILES['fileFF']['name'];
$filetype = $_FILES['fileFF']['type'];
$boundary = md5(date('r', time()));
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"_1_$boundary\"";
$message="
--_1_$boundary
Content-Type: multipart/alternative; boundary=\"_2_$boundary\"
--_2_$boundary
Content-Type: text/plain; charset=\"utf-8\"
Content-Transfer-Encoding: 7bit
$message
--_2_$boundary--
--_1_$boundary
Content-Type: \"$filetype\"; name=\"$filename\"
Content-Transfer-Encoding: base64
Content-Disposition: attachment
$attachment
--_1_$boundary--";
}
mail($to, $subject, $message, $headers);
}
?>
$message = "Имя: ".$_POST['nameFF']."\nEmail: ".$from."\nСообщение: ".$_POST['messageFF'];
заменить на
$message = "Имя: ".$_POST['nameFF']."\nEmail: ".$from."\nСообщение: ".$_POST['messageFF']."\nIP: ".$_SERVER['REMOTE_ADDR'];
Затем при обнаружении IP, рассылающего спам
mail($to, $subject, $message, $headers);
ограничить условием
if($_SERVER["REMOTE_ADDR"] != 0.000.000.000) {
mail($to, $subject, $message, $headers);
}
The requested method POST is not allowed for the URL /demo/index.html
Вам нужно создать страницу с расширением .php и весь код в неё добавить или подключить php на HTML страницах (служба поддержки хостера должна подсказать как, чаще добавляется строка в .htaccess)
if ($filesize < 10000000) {
mail($to, $subject, $message, $headers);
$output = '<script>alert("Ваше сообщение получено, спасибо!");</script>';
} else {
$output = '<script>alert("Извините, письмо не отправлено. Размер всех файлов превышает 10 МБ.");</script>';
}
напишите только
mail($to, $subject, $message, $headers);
$output = '<script>alert("Ваше сообщение получено, спасибо!");</script>';
килобайт (КБ) = 1024 байта
мегабайт(МБ) = 1024 килобайта
10 МБ = 10485760 байт (тут всё сравнительно верно)
А дальше не поняла. Прикрепляются два файла по 1 МБ, в итоге сумма получается 2МБ. Но форма выдаёт ошибку, что превышен размер?
$subject = "Заполнена контактная форма с ".$_SERVER['HTTP_REFERER'];
написать
$subject = 'Заполнена контактная форма с '.$_SERVER['HTTP_REFERER'];
$subject = "=?utf-8?b?". base64_encode($subject) ."?=";
Письма отправляются без проблем, но вложений нет, подскажите в чем загвоздка, или это проблема в хостинге и нужно настроить разрешение на запись?
1) http://shpargalkablog.ru/2015/02/multiple-files-php.html
2) http://shpargalkablog.ru/2014/05/email-file-php.html
<!DOCTYPE HTML>
email нужно добавлять в php
адрес
Подскажите, пожулайста, в какую сторону "копать" ?
С PHP не имел дела ранее, но знания js помогли правильно разобраться во внедрении Вашего обработчика.
В итоге письмо после submit пришло всего два раза (причем, на разные адреса по одному разу... менял, думал беда в почтовиках).
Alert срабатывает каждый раз "успешно".
Заранее благодарю за помощь! Возможно, исходник нужно прикрепить, чтобы Вы смогли понять..?
С уважением, Александр.
Попробуйте удалить заголовки:
$headers .= "From: " . $from . "\r\n";
$headers .= "Reply-To: " . $from . "\r\n";
У меня с ними тоже Яндекс режет письма.
Заголовки эти сразу удалил и не использовал.
Оставил только эти два:
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
Возможно, еще в где-то проблема может быть?
Попробуйте второй вариант, тоже самое, но почему-то лучше срабатывает.
А форма без файлов нормально работает http://shpargalkablog.ru/2014/01/feedback-form.html ?
Без файлов пробовал до этого, но не по вашему шаблону. Срабатывала каждый раз.
Нашел логи с сервера и заметил ошибку наконец-то свою. Может кто-то когда-то столкнется с такой же ситуацией.
Конкретные строчки из лога:
PHP Warning: is_uploaded_file() expects parameter 1 to be string, array given in /путь/к/файлу/contacts.php on line 19, referer: http://ваш.сайт
Я делал прикрепление одного файла, а в html мой инпут имел такой вид:
<"input type="file" name="fileOfClient[]">
Убрав скобки массива "[]" все заработало, при этом письма доходят моментально и с вложением.
В Вашей статье все грамотно отмечено цветом, что обязательно удалить нужно их, но я зря поторопился)))
Благодарю за Ваше решение!
Но... Прошу помочь разобраться в одном недочете.
Ввели все данные, нажали отправить, получаем сообщение:"размер файлов превышает 10 мб".
В этой ситуации из поля "сообщение" пропадает ранее написанный текст. Это нехорошо. В остальных полях информация сохраняется.
Можно с этим что-то сделать?
f.messageFF.removeAttribute('value'); // очистить поле сообщения
f.messageFF.value=''; // очистить поле сообщения
Александр, еще раз спасибо за активное участие!
Но можно как-то сделать, чтобы успешной отправке сообщения текст пропадал, а при ошибке оставался?
Сейчас остается и так, и так.
В принципе я и так доволен))
И еще вопрос..
Для работы формы без ошибок пришлось удалить .htaccess
А без него вроде как нельзя. Можете помочь?
При вынесении скрипта в отдельный файл страница перезагружается и форма не работает.
Это решаемо?
.htaccess удалять не стоит. Смотрите какое именно правило не даёт работать форме. Его (правило) можно ограничить одной страницей, расширением файла и т.п.
Вы имеете ввиду JS?
if (http.responseText.indexOf(f.nameFF.value) == 0) { // очистить поле сообщения, если в ответе первым словом будет имя отправителя
f.messageFF.removeAttribute('value');
f.messageFF.value='';
location.href = "/articles/blog/"; // это как пример ссылки - можешь указать в любом виде (http://google.com) или любую другую
}
Не тестировал, поэкспериментируй.
Возможно есть решения с помощью PHP, конечно.
Работает! Однако, поля имя и e-mail все равно остаются при успешной отправке. Но я в восторге)))
"При вынесении скрипта....." - сам файл .js забыл вынести на сервер)
В .htaccess я вообще не буль-буль..( Буду пыхтеть..
Еще раз спасибо за помощь!)
P.S. Может кому понадобится - location.href = "ваш-сайт"; надо вставлять не вместо if (http.responseText.indexOf(f.nameFF.value) == 0) { // очистить поле сообщения, если в ответе первым словом будет имя отправителя
f.messageFF.removeAttribute('value');
f.messageFF.value=''; или за этими строчками, а вот так if (http.responseText.indexOf(f.nameFF.value) == 0) {
f.messageFF.removeAttribute('value');
f.messageFF.value='';
}
}
}
location.href = "http://ваш_сайт";
1) нажать кнопку
2) нажать на файл
3) нажать кнопку CTRL (или SHift, чтобы выделить идущие подряд файлы или нажатой правой кнопкой мышки выделить область из группы файлов)
4) нажать на другой файл
Это стандартная процедура. Можно как в Яндекс.Почте сделать, чтобы при добавлении файлов они суммировались, но это более трудоёмко и не всем может подходить.
Но появилась новая проблема: выходит сообщение "Извините, данные не были переданы" и все формы остаются заполненными , хотя на самом деле на почту все приходит моментально.
Если вместо русс. букв написать англ - тогда выводит нормально англ. буквы.
Когда сообщение отправлено или не отправлено. Вместо русских букв Появляются знаки вопроса. Как это можно исправить?
Если вместо русс. букв написать англ - тогда выводит нормально англ. буквы.
Перед </head> добавьте
<meta charset='utf-8'/>
ПО типу:
--$boundary
Content-Type: text/plain; charset=\"utf-8\"
Content-Transfer-Encoding: 7bit
Может здесь нестыковка
Вобщем не помогло, может еще есть идеи?
header('Access-Control-Allow-Origin: http://блог.ru');
вот так
<?php
header('Access-Control-Allow-Origin: http://блог.ru');
if (isset ($_POST['contactFF'])) {
Соответственно,
http.open("POST", "http://сайт.ru/contacts.php", true);
Словом, для блога, по-моему, слишком много телодвижений, проще оставить данные email.
Можно сделать примитивный текст "Сколько будет 2+2" и рядом поле. В PHP добавить условие: "если поле такое-то имеет value 4, то отправлять сообщение на почту". Можно прикрутить recaptcha Гугл. У Яндекса вроде похожий IP есть.
Теория http://shpargalkablog.ru/2014/05/box-sizing.html
Пример формы https://jsfiddle.net/NMitra/hw29Ld5z/