Проблемы с отправкой формы AJAX

223
20 марта 2018, 02:43

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

САМА ФОРМА

<br/>
<div class="statusMsg"></div>
<br/>
<form method="post" id="fupForm" action="action.php" enctype="multipart/form-data">
    <div class="form-group">
        <label for="username">Ваше имя</label>
        <input type="text" class="form-control" name="username" placeholder="Иван Петрович" >
    </div>    
    <div class="form-group">
        <label for="email">Ваш Email</label>
        <input type="email" class="form-control" name="email" placeholder="Email" >
    </div>
    <div class="form-group">    
        <label for="image">Изображение:<br>
        </label>    
        <input type="file" name="image" id="file">
        <p class="help-block">Допустимый формат jpg/gif/png, допустимый размер - не более 320х240 пикселей, размер файла не больше 8192КБ </p>
    </div>   
    <div class="form-group">
        <label for="task">Задача</label>
        <textarea class="form-control" name="task" rows="5" placeholder="Текст задачи"></textarea>      
    </div>
    <div class="col-xs-12  col-sm-6 col-md-offset-2 col-md-4">
        <p><!-- Модальное окно-->   
            <input type="button" class="btn btn-default btn-block" name="button_Preview" id="button_Preview" value='Предварительный просмотр' data-toggle="modal" data-target="#Preview">
        </p>
    </div>
    <div class="col-xs-12 col-sm-6 col-md-4">
        <p><input type="submit" id="btn_submit" class="btn btn-default btn-block" name="upload" value='Сохранить задачу'></p>
    </div>  
</form>

AJAX-скрипт

$(document).ready(function(e){
$("#fupForm").on('submit', function(e){
    e.preventDefault();
    $.ajax({
        type: 'POST',
        url: 'action.php',
        data: new FormData(this),
        contentType: false,
        cache: false,
        processData:false,
        beforeSend: function(){
            $('#btn_submit').attr("disabled","disabled");
            $('#fupForm').css("opacity",".5");
        },
        success: function(msg){
            $('.statusMsg').html('');
            if(msg == 'ok'){
                $('#fupForm')[0].reset();
                $('.statusMsg').html('<span style="font-size:18px;color:#34A853">Form data submitted successfully.</span>');
            }else{
                $('.statusMsg').html('<span style="font-size:18px;color:#EA4335">Some problem occurred, please try again.</span>');
            }
            $('#fupForm').css("opacity","");
            $("#btn_submit").removeAttr("disabled");
        }
    });
});

});

И обработчик action.php

    <?php
if ((isset($_POST['upload']) == 1) && ($_FILES['image']['size']) > 0)
{
  $msg_box = ""; // в этой переменной будем хранить сообщения формы
  // Код, который будет выполняться, если форма была оправлена:
    // подключение к базе данных
    // (возможно, вам придется настроить имя хоста, имя пользователя и пароль)
  $dbh = new mysqli("localhost", "root", "", "tasker");
  if(mysqli_connect_errno())
  {
    exit("Ошибка подключения к базе данных MySQL: Сервер база данных не доступен!<br>
      Проверте параметры подключения к базе данных.");
  }
  $username = $_POST['username'];
  $email = $_POST['email'];
  $task = $_POST['task'];

  $sPhotoFileName = $_FILES['image']['name']; // get client side file name
if ($sPhotoFileName) // file uploaded
{ $aFileNameParts = explode(".", $sPhotoFileName);
  $sFileExtension = end($aFileNameParts); // part behind last dot
  if ($sFileExtension != "jpg"
    && $sFileExtension != "JPEG"
    && $sFileExtension != "JPG" 
    && $sFileExtension != "png"
    && $sFileExtension != "PNG"
    && $sFileExtension != "gif"
    && $sFileExtension != "GIF")
    { die ("Choose a JPG, PNG, GIF for the photo");
}
  $nPhotoSize = $_FILES['image']['size']; // size of uploaded file
  if ($nPhotoSize == 0)
    { die ("Sorry. The upload of $sPhotoFileName has failed.
      Search a photo smaller than 100K, using the button.");
}
if ($nPhotoSize > 10240000000)
  { die ("Sorry.
    The file $sPhotoFileName is larger than 100K.
    Advice: reduce the photo using a drawing tool.");
}
  // read photo
  $sTempFileName = $_FILES['image']['tmp_name']; // temporary file at server side
  $oTempFile = fopen($sTempFileName, "r");
  $sBinaryPhoto = fread($oTempFile, fileSize($sTempFileName));
  // Try to read image
  $nOldErrorReporting = error_reporting(E_ALL & ~(E_WARNING)); // ingore warnings
  $oSourceImage = imagecreatefromstring($sBinaryPhoto); // try to create image
  error_reporting($nOldErrorReporting);
  if (!$oSourceImage) // error, image is not a valid jpg
  { die ("Sorry.
    It was not possible to read photo $sPhotoFileName.
    Choose another photo.");
}
}
///////////////////////////////////////////////////////////////////////
$nWidth = imagesx($oSourceImage); // get original source image width
  $nHeight = imagesy($oSourceImage); // and height
  // create small thumbnail
  $nDestinationWidth = 320;
  $nDestinationHeight = 240;
  $oDestinationImage = imagecreate($nDestinationWidth, $nDestinationHeight);
  imagecopyresized($oDestinationImage, $oSourceImage,0, 0, 0, 0,$nDestinationWidth, $nDestinationHeight,$nWidth, $nHeight); // resize the image
  ob_start(); // Start capturing stdout.
  imageJPEG($oDestinationImage); // As though output to browser.
  $sBinaryThumbnail = ob_get_contents(); // the raw jpeg image data.
  ob_end_clean(); // Dump the stdout so it does not screw other output.
  //////////////////////////////////////////////////////////////////////////////
  if($_POST['upload'])
  {
    $sBinaryThumbnail = addslashes($sBinaryThumbnail);
    $result=$dbh->prepare("INSERT INTO user (username,email,task,bin_data,filename,filesize,filetype) 
      "."VALUES ('".$username."',
      '".$email."',
      '".$task."',
      '".$sBinaryThumbnail."',
      '".$_FILES["image"]["name"]."',
      '".$size."',
      '".$_FILES["image"]["type"]."')");
    //if(!$result) exit("Ошибка выполнения SQL запроса!");
    echo $result?'ok':'err';
    $result->execute(); 
  }
}
Answer 1

Что бы нормально отдавать ошибки от обработчика формы, я бы передавал в ответ json с типом сообщения и её текстом. На стороне js отправка данных формы идет без ошибок. Немного нужно изменить прием ответа от action.php в js.

Файл action.php

function returnMessage($message){
    echo json_encode($message);
    exit();
}
$message = [];
if ($_FILES['image']['size'] <= 0){
    $message['type'] = 'error';
    $message['text'] = '$_FILES[\'image\'][\'size\'] > 0'; // текст ошибки
    returnMessage($message);
}
$sPhotoFileName = $_FILES['image']['name']; // get client side file name
// file uploaded
if (!$sPhotoFileName){
    $message['type'] = 'error';
    $message['text'] = 'FALSE TO GET $_FILES[\'image\'][\'name\']'; // текст ошибки
    returnMessage($message);
}
$aFileNameParts = explode(".", $sPhotoFileName);
$sFileExtension = end($aFileNameParts); // part behind last dot
if ($sFileExtension != "jpg"
    && $sFileExtension != "JPEG"
    && $sFileExtension != "JPG" 
    && $sFileExtension != "png"
    && $sFileExtension != "PNG"
    && $sFileExtension != "gif"
    && $sFileExtension != "GIF")
{
    $message['type'] = 'error';
    $message['text'] = 'INVALID FILE EXTENSION'; // текст ошибки
    returnMessage($message);
}
$nPhotoSize = $_FILES['image']['size']; // size of uploaded file
if ($nPhotoSize == 0){
    $message['type'] = 'error';
    $message['text'] = 'Sorry. The upload of '.$sPhotoFileName.' has failed. Search a photo smaller than 100K, using the button'; // текст ошибки
    returnMessage($message);
}
if ($nPhotoSize > 10240000000){
    $message['type'] = 'error';
    $message['text'] = 'Sorry. The file '.$sPhotoFileName.' is larger than 100K. Advice: reduce the photo using a drawing tool.'; // текст ошибки
    returnMessage($message);
}
// read photo
$sTempFileName = $_FILES['image']['tmp_name']; // temporary file at server side
$oTempFile = fopen($sTempFileName, "r");
$sBinaryPhoto = fread($oTempFile, fileSize($sTempFileName));
// Try to read image
$nOldErrorReporting = error_reporting(E_ALL & ~(E_WARNING)); // ingore warnings
$oSourceImage = imagecreatefromstring($sBinaryPhoto); // try to create image
error_reporting($nOldErrorReporting);
// error, image is not a valid jpg
if (!$oSourceImage){
    $message['type'] = 'error';
    $message['text'] = 'Sorry. It was not possible to read photo '.$sPhotoFileName.'. Choose another photo.'; // текст ошибки
    returnMessage($message);
}
///////////////////////////////////////////////////////////////////////
$nWidth = imagesx($oSourceImage); // get original source image width
$nHeight = imagesy($oSourceImage); // and height
// create small thumbnail
$nDestinationWidth = 320;
$nDestinationHeight = 240;
$oDestinationImage = imagecreate($nDestinationWidth, $nDestinationHeight);
imagecopyresized($oDestinationImage, $oSourceImage,0, 0, 0, 0,$nDestinationWidth, $nDestinationHeight,$nWidth, $nHeight); // resize the image
ob_start(); // Start capturing stdout.
imageJPEG($oDestinationImage); // As though output to browser.
$sBinaryThumbnail = ob_get_contents(); // the raw jpeg image data.
ob_end_clean(); // Dump the stdout so it does not screw other output.

////////////////////////////////////////////////////////////////////////////// 
$username = $_POST['username'];
$email = $_POST['email'];
$task = $_POST['task'];
if(!isset($_POST['upload'])){
    $message['type'] = 'error';
    $message['text'] = 'NOT ISSET $_POST[\'upload\']'; // текст ошибки
    returnMessage($message);
}
$dbh = new mysqli("localhost", "root", "", "tasker");
if(mysqli_connect_errno()){
    $message['type'] = 'error';
    $message['text'] = 'Ошибка подключения к базе данных MySQL: Сервер база данных не доступен!<br>Проверте параметры подключения к базе данных'; // текст ошибки
    returnMessage($message);
}
$sBinaryThumbnail = addslashes($sBinaryThumbnail);
$result=$dbh->prepare("INSERT INTO user (username,email,task,bin_data,filename,filesize,filetype) 
  "."VALUES ('".$username."',
  '".$email."',
  '".$task."',
  '".$sBinaryThumbnail."',
  '".$_FILES["image"]["name"]."',
  '".$size."',
  '".$_FILES["image"]["type"]."')");
$result = $result->execute();
if(!$result){
    $message['type'] = 'error';
    $message['text'] = 'Ошибка выполнения SQL запроса!'; // текст ошибки
    returnMessage($message);
}
$message['type'] = 'success';
$message['text'] = 'GOOD';
returnMessage($message);

Сама форма и js:

$(document).ready(function(e){ 
		$("#fupForm").on('submit', function(e){ 
			e.preventDefault(); 
			$.ajax({ 
				type: 'POST', 
				url: 'action.php', 
				data: new FormData(this), 
				contentType: false, 
				cache: false, 
				processData:false, 
				beforeSend: function(){ 
					$('#btn_submit').attr("disabled","disabled"); 
					$('#fupForm').css("opacity",".5"); 
					$('.statusMsg').html(''); 
				}, 
				success: function(msg){ 
					msg = jQuery.parseJSON(msg); 
					if(msg.type == 'success'){ 
						$('.statusMsg').html('<span style="font-size:18px;color:#34A853">Form data submitted successfully.</span>'); 
					}else{ 
						$('.statusMsg').html('<span style="font-size:18px;color:#EA4335">Some problem occurred, please try again.</span><p>'+msg.text+'</p>'); 
					} 
					$('#fupForm').css("opacity",""); 
					$("#btn_submit").removeAttr("disabled"); 
				} 
			}); 
		}); 
	});
<div class="statusMsg"></div> 
	<form method="post" id="fupForm" action="action.php" enctype="multipart/form-data"> 
		<div class="form-group"> 
			<label for="username">Ваше имя</label> 
			<input type="text" class="form-control" name="username" placeholder="Иван Петрович" > 
		</div>     
		<div class="form-group"> 
			<label for="email">Ваш Email</label> 
			<input type="email" class="form-control" name="email" placeholder="Email" > 
		</div> 
 
		<div class="form-group">     
			<label for="image">Изображение:<br> 
			</label>     
			<input type="file" name="image" id="file"> 
			<p class="help-block">Допустимый формат jpg/gif/png, допустимый размер - не более 320х240 пикселей, размер файла не больше 8192КБ </p> 
		</div>    
		<div class="form-group"> 
			<label for="task">Задача</label> 
			<textarea class="form-control" name="task" rows="5" placeholder="Текст задачи"></textarea>       
		</div> 
 
		<div class="col-xs-12  col-sm-6 col-md-offset-2 col-md-4"> 
			<p><!-- Модальное окно-->    
				<input type="button" class="btn btn-default btn-block" name="button_Preview" id="button_Preview" value='Предварительный просмотр' data-toggle="modal" data-target="#Preview"> 
			</p> 
		</div> 
		<div class="col-xs-12 col-sm-6 col-md-4"> 
			<p><input type="submit" id="btn_submit" class="btn btn-default btn-block" name="upload" value='Сохранить задачу'></p> 
		</div>   
	</form>

На тесте у меня работает передача данных через ajax, возврат сообщения отработки формы, его разбор в js и отображения пользователю. НЕ проверялась логика обработки данных формы и внесение в БД

Answer 2

Правильней будет сделать так. Сначала собрать данные из обычных полей, потом собрать данные с поля file и уже после этого передать в ajax запрос. Это будет выглядеть так

$(function() {
    $('#form-data').on('submit', function(e){
        e.preventDefault()
        var form = $(this); // Предположу, что этот код выполняется в обработчике события 'submit' формы
        var data = new FormData();  // Для отправки файлов понадобится объект FormData. Подробнее про него можно прочитать в документации - https://developer.mozilla.org/en-US/docs/Web/API/FormData
        // Сбор данных из обычных полей
        form.find(':input[name]').not('[type="file"]').each(function() { 
            var field = $(this);
            data.append(field.attr('name'), field.val());
        });
        // Сбор данных о файле (будет немного отличаться для нескольких файлов)
        var filesField = form.find('input[type="file"]');
        var fileName = filesField.attr('name');
        var file = filesField.prop('files')[0];
        data.append(fileName, file) ;
        // Отправка данных
        var url = 'upload.php';
        $.ajax({
            url: url,
            type: 'POST',
            data: data,
            contentType: false,
            cache: false, 
            processData:false, 
            success: function(response) {
                console.log(response)
            }           
        });  
    })          
});

Проблема возврата ответа сервера у Вас в echo $result?'ok':'err'; Выполняйте запрос и если запрос выполняется успешно, то возвращайте что-то подобное

if($result->execute()){
   $answer = ['type' => 'success', 'text' => 'Success'];
}
else{
  $answer = ['type' => 'error', 'text' => 'Error'];
}

На стороне клиента уже разобрать этот ответ

success: function(data){
    var response = jQuery.parseJSON(data)
    if(response.type == 'success'{
       /*******
    }
    if(response.type == 'error'){
      /****
    }      
}
READ ALSO
Запрет доступа с правильным паролем MySQL 5.7.21-0 (ubuntu 0.16.04.1)

Запрет доступа с правильным паролем MySQL 5.7.21-0 (ubuntu 0.16.04.1)

Программа на php, подключается к базе командой

220
Работало в php 5.4, но не работает в 7.0 [требует правки]

Работало в php 5.4, но не работает в 7.0 [требует правки]

Помогите пожалуйста поправить этот файл под php 70 Этот файл отвечает за ajax на сайте

184
Как вытянуть всю аппаратную информцию с сервера через PHP?

Как вытянуть всю аппаратную информцию с сервера через PHP?

Как вытянуть всю аппаратную информцию с сервера через PHP при условии что shell для пользователя хостинга заблокирован?

186
Как запустить функцию, написанную на php

Как запустить функцию, написанную на php

Как привязать ее к кнопке что-бы при нажатии выполнялся данный код, если <a onclick="donateUser();" class="orange_button money">Подтвердить</a> не работает

195