У меня возникает странная проблема: вызов формы ajax с несколькими файлами и значениями формы работает идеально, но только при втором вызове. Первый вызов завершается условием success: function (result) «else». Второй звонок работает отлично и отправляет все данные в php. Таким образом, я нажимаю кнопку отправки один раз, и появляется пустое окно с ошибкой, и я снова нажимаю кнопку отправки, и все работает отлично.

Как это возможно и как это решить?

ОБНОВЛЕНИЕ № 1: Обходной путь, но не решение. Это работает, когда я помещаю if (result==="") { $(".form-application").submit(); } ниже функции успеха. Но это очень грязно! ... и загрузить все файлы дважды! :-(

ПРОБЛЕМА РЕШЕНА Дэвид Найп предоставил решение !! Огромное спасибо!!

ДЖКЕРИ:

    $(".form-application").submit(function(e) {
        e.preventDefault();
        $("#btnSubmit2").text("Please wait...");
        $("#btnSubmit2").attr("disabled", true);    
        var files = $('#files')[0].files;
        var form = $(this);
        var error='';       
        var formData = new FormData(this);
        grecaptcha.ready(function() {
            grecaptcha.execute('6Le4Qb0UAAAAAHUPcsmVYIk7zc4XCsiBnf6oE-fP', {action: 'create_comment'}).then(function(token) {
                $('<input>').attr({
                    type: 'hidden',
                    value: token,
                    name: 'token'
                }).appendTo('form');

        for(var count = 0; count<files.length; count++)
        {
        var name = files[count].name;
        var extension = name.split('.').pop().toLowerCase();
        if(jQuery.inArray(extension, ['gif','png','jpg','jpeg']) == -1)
        {
            error += "Invalid " + count + " Image File"
        }
        else
        {
            formData.append("files[]", document.getElementById('files').files[count]);
        }
        }                   
        if(error == '')
        {                   
            $.ajax({
                url: form.attr("action"),
                method: form.attr("method"),
                data: formData,
                processData: false,
                contentType: false,
                success: function(result) {
                if (result == "0") {
                    $("#btnSubmit2").text("Thank you!");
                    $("#btnSubmit2").attr("disabled", true); 
                    $(".output_message").text("");              
                    $(':input','.form-application')
                    .not(':button, :submit, :reset, :hidden')
                    .val('')
                    .prop('checked', false)
                    .prop('selected', false);
                    $(".output_message").append("<div class='alert alert-success alert-dismissible fade show' role='alert'>We have received your application!</div>");                          
                } else {
                    $(".output_message").text("");
                    $(".output_message").append("<div class='alert alert-danger alert-dismissible fade show' role='alert'>"+result+"</div>");       
                    $("#btnSubmit2").attr("disabled", false); 
                    $("#btnSubmit2").text("try again");
                }
            }
            });     
        }
        else
        {
        alert(error);
        }   
        });
        });
        return false;
    });

HTML:

      <form class="form-application" id="applicationform" method="post" action="https://<?PHP echo $_SERVER['HTTP_HOST']; ?>/include/process-application.php" enctype="multipart/form-data"> 
      <input type="hidden" name="crsf" value="<?=$_SESSION['crsf']?>"/>
      <input type="hidden" name="crsf-expire" value="<?=$_SESSION['crsf-expire']?>"/>       
      <div class="space40"></div>
      <h6>Name</h6>
      <input name="name" type="text" class="form-control" placeholder="Your Name">
      <div class="space30"></div>        
      <h6>Email</h6>
      <input name="email" type="text" class="form-control" placeholder="Your Email Address">
      <div class="space30"></div>
      <h6>Instagram Name</h6>
      <input name="instagram" type="text" class="form-control" placeholder="Your Instagram Name">
      <div class="space30"></div>
      <h6>City & Country</h6>
      <input name="from" type="text" class="form-control" placeholder="Where do you live?">
      <div class="space30"></div>
      <h6>Tell us more about you</h6>
      <textarea name="message" class="form-control" rows="3" placeholder="Write some details about you, so we know you better."></textarea>
      <div class="space30"></div> 
      <h6>Upload some photos of yourself</h6>         
      <div class="file-field">
      <div class="btn btn-aqua">
        <input name="files" id="files" type="file" accepts="image/*" multiple>
      </div>
      <div class="file-path-wrapper">
      </div>
      <div class="space20"></div>         
      </div>      
      </div>
       <div class="col-12 text-center">
         <button id="btnSubmit2" type="submit" class="btn btn-full-rounded btn-aqua">Submit Application</button>
         <div class="space10"></div>              
         <span class="output_message"></span>   
       </div>   
       </form>

PHP Script /include/process-application.php

<?PHP
echo "0"; 
?>
1
tms99 25 Окт 2019 в 18:22

2 ответа

Лучший ответ

Хорошо, я думаю, что я понял это. $('<input>').attr(...); устанавливает атрибут токена для нового элемента <input>. Но это после var formData = new FormData(this);, поэтому токен не включается в formData. Тогда, я думаю, вы получите ошибку аутентификации, и я предполагаю, что она выполняет аутентификацию еще до того, как дойдет до части PHP. Это будет просто ответ HTTP401 без тела, следовательно, "". Но затем, со второй попытки, <input> уже был создан с правильным токеном, и это в конечном итоге используется для аутентификации.

0
David Knipe 25 Окт 2019 в 20:44

Либо продолжай подчиняться, либо действуй. Удалить действие из тега формы, оно будет работать

0
Somnath Ghosh 25 Окт 2019 в 17:32
58561398