Как я могу загружать файлы с помощью ajax без выполнения submit?


я пытаюсь выполнить огромную форму, которая состоит из нескольких частей.

одной из частей является загрузка исследований соответствующего лица, для этого, используя input file, вы можете загружать файлы названий исследований (1 каждый раз):

<div class="formContainer cvFormContainer">
        <p class="formTitle">Create a new CV</p>
        <form id="cvDataForm" method="post" enctype='multipart/form-data'>
          <div class="formDataContainer">
            <div class="personalDataCategory"><h2 class="categoryTitle">Initial data</h4>
              <div id="initialFormError"><!-- Error will be shown here ! --></div>
              <!-- INITIAL DATA  -->
              <fieldset>
                <label for="cvName"><span class="labelText">Name</span></label>
                <input type="text" id="cvName" placeholder="Name" name="cvName" minlength="2" maxlength="100" value=''>
                <label for="surname1"><span class="labelText">Surname 1</span></label>
                <input type="text" class='formInputLeft' placeholder="Surname 1" name="surname1" minlength="2" maxlength="100" value=''>
                <label for="surname2"><span class="labelText">Surname 2</span></label>
                <input type="text" placeholder="Surname 2" name="surname2" minlength="2" maxlength="100" value=''>

                <label for="phone1"><span class="labelText">Phone number</span></label>
                <input type="number" placeholder="phone" name="phone1" minlength="2"  value=''>

                <label for="phone2"><span class="labelText">Phone number 2</span></label>
                <input type="number" placeholder="phone" name="phone2" minlength="2" autocapitalize="off" value=''>

                <label for="address"><span class="labelText">Address</span></label>
                <input type="text" placeholder="address" name="address" minlength="10" maxlength="300" autocapitalize="off" value=''>

                <label for="cvMail"><span class="labelText">Email</span></label>
                <input type="email" placeholder="Enter email" id="cvMail" name="cvMail" autocapitalize="off" value=''>

                <label for="birthdate"><span class="labelText">Birthdate</span></label>
                <input type="date" id="birthdate" name="birthdate" value=''>

                <button  id="btnSaveInitialData" name="btnSaveInitialData">Save data</button>
              </fieldset>
            </div>
            <!-- ADITIONAL DATA  -->
            <div class="aditionalCVCategory" id="aditionalCVDataForm"><h2 class="categoryTitle">Aditional data</h4>
              <fieldset>
                <label for="maritalStatus" class='labelText'>Marital status<br></label>
                <label><input type="radio" class="formRadioInputs" name="maritalStatus" value='Single'>Single<br></label>
                <label><input type="radio" class="formRadioInputs" name="maritalStatus" value='Married'>Married<br></label>
                <label><input type="radio" class="formRadioInputs" name="maritalStatus" value='Divorced'>Divorced<br></label>
                <label><input type="radio" class="formRadioInputs" name="maritalStatus" value='Widowed'>Widowed<br></label>

                <label for="salarialExpectatives"><span class="labelText">Salarial Expectatives</span></label>
                <input type="number" id="salarialExpectatives" min="0" step="any" name="salarialExpectatives">

                <label for="childrenNumber"><span class="labelText">Children number</span></label>
                <input type="number" id="childrenNumber" min="0" name="childrenNumber" autocomplete="off">

                <label class='labelText'>Driving license<br></label>
                <label><input type="checkbox" class="formCheckInputs" name="drivingLicenseA" value="1">A</label>
                <label><input type="checkbox" class="formCheckInputs" name="drivingLicenseB" value="1">B</label>
                <label><input type="checkbox" class="formCheckInputs" name="drivingLicenseC" value="1">C</label>
                <label><input type="checkbox" class="formCheckInputs" name="drivingLicenseD" value="1">D<br></label>

                <label class='labelText'>Skills<br></label>
                <label><input type="checkbox" class="formCheckInputs" name="skNav" value="1">NAV</label>
                <label><input type="checkbox" class="formCheckInputs" name="skSap" value="1">SAP</label>
                <label><input type="checkbox" class="formCheckInputs" name="skA3" value="1">A3</label>
                <label><input type="checkbox" class="formCheckInputs" name="skOffice" value="1">Office<br></label>

                <label for="role" class='labelText'>Department that will apply to</label>
                <?php
                  $userListHandler = PrintDataHandler::getInstance();
                  $userListHandler->printDepartmentSelect();
                 ?>
                <button id="btnSaveAditionalCVData" name="btnSaveAditionalCVData">Save data</button>
              </fieldset>
            </div>
            <!-- LANGUAGES -->
            <div class="LanguagesCategory" id="cvLanguagesForm"><h2 class="categoryTitle">Languages</h4>
              <fieldset>
                <div class="leftDataContent">
                  <?php
                    $userListHandler = PrintDataHandler::getInstance();
                    $userListHandler->printLanguageSelect();
                   ?>
                  <label for="languageLevel" class='labelText'>Level<br></label>
                  <label><input type="radio" class="formRadioInputs" name="languageLevel" value="1" >Basic</label>
                  <label><input type="radio" class="formRadioInputs" style="margin-left:10px" name="languageLevel" value="2" >Intermedian</label>
                  <label><input type="radio" class="formRadioInputs" style="margin-left:10px" name="languageLevel" value="3" >Expert</label>
                  <label><input type="radio" class="formRadioInputs" style="margin-left:10px" name="languageLevel" value="4" >Bilingual</label>
                </div>
                <div class="rightAddButtonContainer">
                  <button class="addButton" id="btnAddLanguage" name="btnAddLanguage"><img class="imgAddButton" src="../resources/icons/add.png" alt="add image"></button>
                </div>
              </fieldset>
              <div class="languagesContainer">
                <h3 class='currentLanguagesTitle'> Current Languages </h3>
                <div id="languageDataContainer"></div>
              </div>
            </div>
            <!-- STUDIES -->
            <div class="StudiesCategory" id="cvStudiesForm"><h2 class="categoryTitle">Studies</h4>
              <fieldset>
                <div class="leftDataContent">
                  <label for="cvDegree"><span class="labelText">Degree</span></label>
                  <input type="text" placeholder="degree" name="cvDegree" minlength="2" maxlength="100">
                  <label for="cvStartingYear"><span class="labelText">Starting year</span></label>
                  <select name="cvStartingYear" id="cvStartingYear">
                    <?php for ($year=1900; $year <= 2018; $year++): ?>
                      <option value="<?php echo $year;?>"><?php echo $year;?></option>
                    <?php endfor; ?>
                  </select>
                  <label for="cvEndingYear"><span class="labelText">End year</span></label>
                  <select name="cvEndingYear" id="cvStartingYear">
                    <?php for ($year=1900; $year <= 2018; $year++): ?>
                      <option value="<?php echo $year;?>"><?php echo $year;?></option>
                    <?php endfor; ?>
                  </select>
                  <label for="cvAcademy"><span class="labelText">Academy</span></label>
                  <input type="text" placeholder="Academy" name="cvAcademy" minlength="2" maxlength="200">
                  <label for="cvStudiesFile"><span class="labelText">Studies files</span></label>
                  <input type="file" id="cvStudiesFile" name='cvStudiesFile' />

                </div>
              <div class="rightAddButtonContainer">
                <button class="addButton" id="btnAddStudy" name="btnAddStudy"><img class="imgAddButton" src="../resources/icons/add.png" alt="add image"></button>
              </div>
            </fieldset>
            <div class="studiesContainer">
              <h3 class='studiesContainerTitle'> Current Studies </h3>
              <div id="studiesDataContainer"></div>
            </div>
          </div>
        </form>
      </div>
    </div>

Эта форма при нажатии кнопки add вызовет функцию jquery:

$(document).ready(function() {
  $('#btnAddStudy').click(function(e) {
    e.preventDefault();
    var partialData = $(this).closest('fieldset').serialize();
    var csvFile = $('#cvStudiesFile')[0].files[0];
    var data = new FormData();
    data.append('data', partialData);
    data.append('file', csvFile);
    $.ajax({
      type: 'POST',
      url: '../php/addStudiesProcess.php',
      data: data,
      dataType: 'json',
      success: function(response) {

      },
    });
    return false;
  });
});

который отправит по почте все данные.

сначала загрузите данные для всех поля, кроме самого файла, благодаря тому, что он собирает все данные из соответствующего fieldset (у меня есть несколько групп, выше один образец).

я пытался сделать console.log(data), и я не вижу, чтобы файлы были прикреплены.

как я могу отправить файлы без выполнения submit в форме?

PS: форма имеет enctype <form id="cvDataForm" method="post" enctype='multipart/form-data'>

отредактировано: я помещаю целую форму, чтобы не было путаницы.

прочитав ответы, я изменил файл jquery, но параметры, которые я получаю:

-----------------------------1760555163458
Content-Disposition: form-data; name="data"

cvDegree=asdasdas&cvStartingYear=1907&cvEndingYear=1916&cvAcademy=IES%20Ntra%20Sra%20De%20Los%20Remedios
-----------------------------1760555163458
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

example

-----------------------------1760555163458--

идея состояла бы в том, чтобы получить параметры типа $_POST.

Author: ramon guardia, 2018-04-24

2 answers

Вы можете создать объект типа FormData к которому вы добавите частичные данные, полученные с помощью serialize, а также файл.

Кроме того, вы должны указать в запросе ajax два других значения:

  • contentType: false и
  • processData: false

Я попробовал этот код, и он отлично работает для меня. Я воспользовался, чтобы написать запрос Ajax в соответствии с современным временем, учитывая, что jQuery 3 объявил используемые функции success и error устаревшими традиционно для управления запросами Ajax. Они рекомендуют использовать doneи fail.

$( function() { /*preferible a document.ready, el cual es obsoleto desde jQuery 3*/

  $('#btnAddStudy').click(function(e) {
    e.preventDefault();
    var partialData = $(this).closest('fieldset').serialize();
    var csvFile=$('#cvStudiesFile')[0].files[0];
    var data = new FormData();
    data.append('data',partialData); 
    data.append('file', csvFile);

    var request = $.ajax
        ({
            url: '../php/addStudiesProcess.php',
            method: 'POST',
            contentType: false,
            processData: false,
            data: data,
            dataType: "json"
        });

        request.done(function( msg )
        {
            console.log("hecho: "+msg);

        });

        request.fail(function( jqXHR, textStatus )
        {
            alert( "Hubo un error: " + textStatus );
        });

  });    

});

# # PHP

Обратите внимание, что в данных, которые вы отправляете, будет два ключа: data и file. Я говорю это для вас, чтобы иметь в виду в isset PHP.

  • Чтобы восстановить данные, вы должны получить доступ к $_POST['data']. Это будет массив, который будет содержать различные сериализованные значения. Например:

     $arrDatos=$_POST['data'];
     $startYear=$arrDatos['cvStartingYear']; /*Aquí estaríamos accediendo a uno de los valores dentro del POST*/
    
  • , Чтобы получить файл вы должны получить доступ к $_FILES['file']

Примечание: поскольку вы указали dataType: 'json' в запросе Ajax, ваш PHP-скрипт не может ответить на что-либо другое , кроме действительного json, иначе вы будете иметь право на parse error .... Если вы хотите обрабатывать другой тип ответа, вы должны изменить dataType на html или другой.


Постскриптум

В некоторых случаях, согласно комментарию OP, вам нужно будет прочитать часть данных, которые не являются файлами с помощью parse_str().

Например:

parse_str($_POST["data"], $mData);

Здесь Часть data POST будет всем, что мы поместили в partialData на клиенте, и теперь мы будем использовать $mData для получения значений, например:

echo $mData["cvName"]; //...etc
 5
Author: A. Cedano, 2020-10-20 15:47:28

Чтобы загрузить файл на сервер с помощью AJAX, вы можете основываться на следующем коде.

function cargaArchivo(){
    var formData    = new FormData(document.getElementById("formvalida"));

    $.ajax({
        url:            "loadFile",
        type:           "post",
        async:          "false",
        dataType:       "JSON",
        data:           formData,
        cache:          false,
        contentType:    false,
        processData:    false

    })
    .done(function(result) {
        console.log(result);
    })
    .fail(function() {
        console.log("error en cargaArchivo()");
    })
}

Чтобы получить данные, отправленные из AJAX с помощью PHP, вы можете взять в качестве примеров следующий фрагмент кода.

public function loadFile(){

    # Si necesitas ver todo el contenido del request _FILE
    # echo "<pre>"; 
    # print_r($_FILE);
    $adjunto['error'] = $_FILES['adjunto']['error'];
    $adjunto['name']  = $_FILES['adjunto']['name'];

    echo json_encode($adjunto);

}

Надеюсь, что я помог,

С наилучшими пожеланиями ЭКГ.

 0
Author: Elias Catalan, 2018-04-24 12:29:44