09.10.2017, 21:43
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
1) Зачем именно так проверять - data.ok == '1'? Функции json_encode задайте опцию JSON_NUMERIC_CHECK и числа будут как числа - json_encode($message_ok, JSON_NUMERIC_CHECK);
2) print json_encode($message_ok); - такое допустимо только в том случае если это и есть завершение кода, иначе может быть не контролируемый вывод в браузер (например после закрывающего тега РНР есть пробелы, переводы строк, ...), что породит ошибку и вы ничего не получите в success. Ошибки либо в другом методе Ajax проверять, либо в success в соответствующем аргументе функции.
Уж коли это завершение работы, то лучше так:
$message = mail($mailto, $subject, $multipart, $headers) ? ["ok" => 1, "text" => "Все Ок"] : ["ok" => 2, "text" => "Увы, ошибка"];
exit(json_encode($message, JSON_NUMERIC_CHECK));
Учтите, что mail возвращает информацию всего лишь об успешной или нет передаче отправления в sendmail. Эта функция не проверяет ошибок, ни того что почта отправлена. Ошибки могут прийти на сервер потом, после реального отправления почты.
|
|
10.10.2017, 08:21
|
Новичок на форуме
|
|
Регистрация: 09.10.2017
Сообщений: 8
|
|
Большое спасибо! Все получилось!
Сделала так. Концовка php файла отправки:
if (!mail($mailto, $subject, $multipart, $headers)) {
$err = array("ok" => 2, "message_text" => "n");
exit(json_encode($err, JSON_NUMERIC_CHECK));
} else {
$message = array("ok" => 1, "message_text" => "y");
exit(json_encode($message, JSON_NUMERIC_CHECK));
}
Скрипт:
e.preventDefault(); //отменяем действие по умолчанию - отправление формы
//и отправляем ее посредством Ajax, используя при этом jQuery
$.ajax({
url: this.action, //url запроса можно брать из формы, таким образом можно использовать этот обработчик для многих форм
type: this.method, //метод запроса также берем из формы
contentType: false, //обязательно
processData: false, //обязательно
data: new FormData(this), //получаем данные формы
dataType: 'json',
success: function (data) {
if (data.ok == 1) {
$('form[name="calcprojectform1"]')[0].reset();
$('form[name="calcprojectform1"]').replaceWith('<div style="padding:15px;background:#fff; font-size:14px;font-family:MuseoSansCyrl_700; color:green;">Спасибо, ваш вопрос успешно отправлен.</div>')
}
if (data.ok == 2) {
$('#calc-project-submit1').validationEngine('showPrompt', 'Ошибка отправки данных. Попробуйте позже.');
}
}
});
Все работает! Даже не вериться...
|
|
10.10.2017, 10:06
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от KateU
|
Даже не вериться...
|
Да нет ничего сверх естественного в этом, наоборот, это закономерность.
Обмен с сервером происходит в формате JSON и если до его или после его передачи будет любой вывод в браузер, то на клиенте в итоге получится невалидный json. jQuey в этом случае конечно же генерирует ошибку, но она передается не первым аргументом функции в success. Первый аргумент этой функции, это данные возвращенные сервером и в случае json, это будет объект - результат его декодирования. Но при ошибке этот аргумент будет пуст. Вы же не проверяете ошибок, видите что ничего нет, и вам и кажется, что сервер не отвечает, хотя на самом деле ответ есть (его можно и в отладчике браузера увидеть).
Проверить можно было бы и так - dataType: 'text' на время проверки, и вы увидите json-строку, но по ней вряд ли можно определить валидная ли она если "мусор" передающийся с ней, это непечатные символы: пробелы, переносы строк, ВОМ и т.п.
И зачем дважды прописывать операции - exit(json_encode... Определили по условиям данные, а затем вывод их один раз прописанный. В данном случае тернарный оператор более лаконичен, хотя это и не важно.
Если скрипт пишется под версию 5.4 и выше, то можно меньше нагружать пальцы свои, объявляя массивы точно также как это можно и в JS - ["ok" => 2, "message_text" => "n"]; вместо array("ok" => 2, "message_text" => "n");
А это просто замечание:
Один бит может иметь два состояния, двумя битами можно описать четыре состояния. То есть значением одной переменной "ok" можно описать два условия, а двумя - "ok" и "message_text" четыре. У вас же переменная "ok" уже сообщает клиенту результат выполнения, зачем при этом нужен "message_text", который в любом случае имеет одно и тоже значение?
$('#calc-project-submit1').validationEngine('showPrompt', 'Ошибка отправки данных. Попробуйте позже.'); - сподручнее это текст как раз и определять серверу причем не в скриптах обработчиках, а как определенные переменные сообщений, значений и т.п., дабы и в клиентских скриптах не оперировать строками, которые в случае их замены придется искать и править. И это как раз и можно было бы определять как ["ok" => 2, "message_text" => $error];, а в случае удачи ее просто не будет - не нужна, или же есть но сообщает о "Спасибо, ваш вопрос успешно отправлен" - ["ok" => 1, "message_text" => $message_mail];.
Последний раз редактировалось laimas, 10.10.2017 в 10:10.
|
|
10.10.2017, 10:49
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Вот это - $('form[name="calcprojectform1"]')... тоже лишнее так как форма в обработчике изначально уже " в ваших руках", это this. Чтобы ее оперировать в последствии ее нужно просто "запомнить". То есть:
$('#calcprojectform1').on('submit', function (e) {
e.preventDefault();
var f = this; //это форма
//далее этой переменной оперировать
url: f.action,
type: f.method,
//......
//и в результате
f.reset(); //правда не понятно для чего, если далее она заменяется элементом DIV
$(f).replaceWith(....
Но если с прицелом на "таким образом можно использовать этот обработчик для многих форм", то не должно быть $('#calcprojectform1'). Формы должны иметь общий для всех идентификатор, отправление которых будет обрабатываться этим обработчиком. Таким идентификатором может служить общее имя класса или часть имени класса/id.
Но и этого мало - должен быть единый "определенный протокол/логика" обмена данных между клиентом и сервером. Например, если формат всегда json (что не обязательно, и выгоднее не указывать его в dataType: 'json', а определять сервером через заголовки, клиент же на основе типа данных может поступать так или иначе), поместить некие данные в какой либо элемент на странице и выполнить некие функции сервером можно задать так:
['insert' =>['box1' => 'Text', 'box2' => '<p>HTML</p>'], 'exe' => ['fun1' => [1, 2], 'fun2' => 'abc']]
По приему такого json клиент определяет наличие в нем ключа 'insert' и если есть вставляет данные в элементы с id 'box1', 'box2', а также при наличии ключа 'exe' выполняет функции 'fun1' и 'fun2' с указанными аргументами, и которые прописаны например в каком либо объекте.
Это на заметку - так как ответ сервера не обязательно будет быстрым, на время запроса кнопку submit нужно делать недоступной, и вновь доступной после ответа сервера.
|
|
10.10.2017, 11:10
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Ну и самое главное - ваш скрипт почтового отправления не проверяет данные, а это очень плохо. Если вы рассчитываете на validationEngine(), то зря, это сервис для клиента чтобы не делать лишних запросов сервера. Но эта проверка рассчитана на "хороших парней", а для ботов это игрушка. Если сервер будет полагаться на проверку клиентом, та ваша почта становится потенциальной дырой для отправления через нее чего угодно и кому-угодно.
|
|
10.10.2017, 14:12
|
Новичок на форуме
|
|
Регистрация: 09.10.2017
Сообщений: 8
|
|
Спасибо большое. Теперь все это нужно осознать и упростить код.
А что вы имеете в виду под проверкой данных? На какие условия рекомендуете проверять?
|
|
10.10.2017, 14:23
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
KateU, нужно проверять удовлетворяют ли полученные от пользователя данные вашим ожиданиям или нет.
Например если вы ожидаете от пользователя его возраст, то нужно удалить из полученных данных все, кроме цифр.
Если ожидаете строку без спец. символов, то нужно удалить все спец. символы из полученных данных.
Если после обработки вы собираетесь записать данные в бд, то нужно произвести экранизацию некоторого кол-ва символов (применения «mysqli_escape_string» обычно хватает).
|
|
10.10.2017, 14:37
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от KateU
|
На какие условия рекомендуете проверять?
|
Например - я возьму и вот в это $_POST['mail'] вставлю множество адресов, и если ваш скрипт меня "обрадует" тем, что письмо успешно отправлено, то единственный вывод, который я сделаю, это "проверкой данных извне на сервере даже не пахнет". Думаю не трудно догадаться каким образом я использую отправку почты от имени вашего домена. Кстати, по причине "дырявости кода" с использованием функции mail, который к сожалению не редкость (только на этом форуме таких дырявых кодов показано не мало), хостеры запрещают использовать функцию mail, предлагая SMTP серверы таких гигантов как Гугл, Яндекс и т.д.
Ну а если "ради шутки", то могу вам слать всякий мусор, ваш же код добросовестно его будет принимать и отдавать sendmail. Ну разве же это почта? Порт 25, это тот порт, за которым ваш хостер следит, и если из-за этого порта у него появятся проблемы, не ждите ничего хорошего от хостера в свой адрес.
Есть готовые классы грамотно оформляющие почтовые отправления, тот же phpmailer, можете использовать его или же если сами, то более ответственно относитесь к данным извне.
Последний раз редактировалось laimas, 10.10.2017 в 14:42.
|
|
|
|