Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 24.09.2015, 22:28
Кандидат Javascript-наук
Отправить личное сообщение для drkrol Посмотреть профиль Найти все сообщения от drkrol
 
Регистрация: 09.10.2013
Сообщений: 114

Подскажите, как сюда прикрутить 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. Еще остаётся вопрос, как добавить анимацию загрузки? В какую строчку его засунуть ?
Ответить с цитированием
  #2 (permalink)  
Старый 24.09.2015, 22:43
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

var http = new XMLHttpRequest().... это и есть Ajax, чего еще добавлять, кроме как обработку ответов сервера.

$subject = "Заполнена контактная форма с ".$_SERVER['HTTP_REFERER']; - так нельзя отправлять тему сообщения, ее нужно кодировать.

И принимать так файлы тоже нельзя - нужно уже на клиенте знать параметры сервера, которые накладывают ограничения на загрузку файлов.
Ответить с цитированием
  #3 (permalink)  
Старый 24.09.2015, 23:51
Кандидат Javascript-наук
Отправить личное сообщение для drkrol Посмотреть профиль Найти все сообщения от drkrol
 
Регистрация: 09.10.2013
Сообщений: 114

1) ajax - это jquery, а текущий код работает без jquery. Тогда выходит, что var http = new XMLHttpRequest().... не ajax...
2)если было бы нельзя, то ничего бы не работало... Но всё работает.
Всё перестаёт работать, когда я пытаюсь прикрутить ajax)
Ответить с цитированием
  #4 (permalink)  
Старый 25.09.2015, 01:04
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Сообщение от drkrol
ajax - это jquery
Это с каких пор Ajax стал принадлежать jQuery? Вы бы хотя бы читали, что это такое, а не пороли.... То что в jQuery есть методы работающие с Asynchronous Javascript and XML (Ajax - «асинхронный JavaScript и XML») еще не означает, что это ее детище. А XMLHttpRequest() это просто объект, который и служит для асинхронного обмена, и который используется и jQuery, нет у него своего объекта.

Сообщение от drkrol
если было бы нельзя, то ничего бы не работало... Но всё работает.
Вы в этом уверены? Кодировать надо тему сообщения и подстановки к адресу потому, что объявляемый вами charset не затрагивает их. И с большой долей вероятности вместо текста на каком либо почтовом сервисе или в почтовом клиенте вместо заголовка будет не понять что.

Вы так лихо file_get_contents($_FILES['fileFF']['tmp_name'][$i]), даже не проверяя загружено ли изображение.... и это по вашему работа? Работать с файлами нужно только после проверки ключа "error" на отсутствие ошибок.

Сервер накладывает ограничения на загрузку файлов - на макс. размер файла, на количество файлов и общий размер $_POST данных. Кроме этого любой уважающий себя хост всегда следит за 25 портом и отправлять почту любого размера не позволит.

Работает у вас так, на халяву, пока не гикнут вас с вашим подходом к написания скриптов, и получите вы по шапке. Тогда может задумаетесь как должно работать.

Последний раз редактировалось laimas, 25.09.2015 в 01:19.
Ответить с цитированием
  #5 (permalink)  
Старый 25.09.2015, 13:19
Кандидат Javascript-наук
Отправить личное сообщение для drkrol Посмотреть профиль Найти все сообщения от drkrol
 
Регистрация: 09.10.2013
Сообщений: 114

Сообщение от laimas Посмотреть сообщение
Работает у вас так, на халяву, пока не гикнут вас с вашим подходом к написания скриптов, и получите вы по шапке. Тогда может задумаетесь как должно работать.
Не совсем понял вас... Как это гикнуть на мой подход? Если вы хорошо почитали мой пост, то вы поймёте, что скрипт написал не я, а взял его с сети.

Сообщение от laimas Посмотреть сообщение
Вы так лихо file_get_contents($_FILES['fileFF']['tmp_name'][$i]), даже не проверяя загружено ли изображение.... и это по вашему работа? Работать с файлами нужно только после проверки ключа "error" на отсутствие ошибок
Это уже другой вопрос. Сейчас стоит вопрос только о том как сделать анимацию загрузки и вывести результат через смену стиля (addclass)

Вы так отвечает будто там, в решении моего вопроса, много строк кода...

Прошу знающих людей помочь мне в этом простом для вас, и в сложном для меня деле.
Ответить с цитированием
  #6 (permalink)  
Старый 25.09.2015, 15:16
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Сообщение от drkrol
Как это гикнуть на мой подход?
Да просто - загрузят вам файлов по размеру, за который вам хостер ваш может и по шапке дать. Вам ведь сказано было - так нельзя. А что от вас? Ну почти - "работает да и хрен с ним".

Первым делом, это нужно в панели управления узнать разрешения на почту, обычно это ограничения на количество сообщений отправляемых за единицу времени и на размер почтового отправлений. Из этого размера и нужно исходить, то есть еще на клиенте проверять размер загружаемых файлов, и по приему формы сервером опять проверять, и обязательно!

Сам сервер накладывает ограничения на загрузку файлов, которые тоже можно узнать в панели. Если панель не дает об этом полной информации, то это можно получить таким образом:

//макс. размер 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;

Последний раз редактировалось laimas, 25.09.2015 в 15:31.
Ответить с цитированием
  #7 (permalink)  
Старый 25.09.2015, 16:18
Кандидат Javascript-наук
Отправить личное сообщение для drkrol Посмотреть профиль Найти все сообщения от drkrol
 
Регистрация: 09.10.2013
Сообщений: 114

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, я понятия не имею...
Ответить с цитированием
  #8 (permalink)  
Старый 25.09.2015, 17:18
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Я же просто пишу пример, для единичного файла, а вы загружаете массив файлов, поэтому надо:

$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().

Последний раз редактировалось laimas, 25.09.2015 в 21:47.
Ответить с цитированием
  #9 (permalink)  
Старый 25.09.2015, 19:39
Кандидат Javascript-наук
Отправить личное сообщение для drkrol Посмотреть профиль Найти все сообщения от drkrol
 
Регистрация: 09.10.2013
Сообщений: 114

Спасибо вам за помощь, но вы можете просто сказать, что нужно в 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;
});
Ответить с цитированием
  #10 (permalink)  
Старый 25.09.2015, 20:47
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Я уже сказал - у вас есть в коде отправка именно Ajax методом - вот непосредственно строка отправки формы http.send(new FormData(f));, прикручивать сюда еще $.ajax jQuery совсем не нужно.

Только нужно добавить проверку на условия, не отправлять форму пока условия не будут соблюдены, а также возвращать ошибки при проверке формы на сервере. В общем нужно добавить диалог-клиент сервер. Ведь не только загрузку файлов проверять надо на сервере, но и заполнение полей необходимых, если они обязательные для заполнения.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как сделать подрузку <div> через ajax? Feniks000 jQuery 1 11.02.2014 09:44
Как вы относитесь к наркоманам? Maxmaxmaximus7 Оффтопик 7 05.02.2014 13:29
Как обработать RadioButton с помощью JavaScript и AJAX MagicDawn AJAX и COMET 6 24.12.2013 20:42
Как ускорить вставку html из ajax? jey7 AJAX и COMET 7 27.05.2012 11:02
Не правильно работает прокрутка, подскажите как сделать правильно? denfer12 Общие вопросы Javascript 0 09.05.2012 00:34