如何通过 jquery $.ajax() 正确传递图像文件?

How to pass an image file thru jquery $.ajax() correctly?

我正在尝试上传图像并通过 ajax 将用户 ID 和文件传递到 PHP 文件 profileSettings.inc.php。然而它在运行 php 文件中成功,但数据没有通过。当我 运行 print_r($_POST); 时,在 php 文件中它返回了一个空数组。

    $(document).ready(function(){
  $("form#profileForm").submit(function(event){
    event.preventDefault();
    var file = $("#file")[0].files[0];
    var userID = $("input[type=hidden][name=userID]").val();
    var uploadProfileSubmit = $('button[name=uploadProfileSubmit]').val();

    $.ajax({
      url: 'includes/profileSettings.inc.php',
      data: {userID: userID, file: file, uploadProfileSubmit: uploadProfileSubmit},
      processData: false,
      contentType: false,
      type: 'POST'
      }).done(function(data){
        $("#settings-msg").html(data);
        alert(data);
    });
  });
});

表格:

<form id="profileForm" class="profileForm" method="post" action="includes/profileSettings.inc.php" enctype='multipart/form-data'>
        <input type="hidden" name="userID" id="userID" value="<?php echo $userID ?>">
        <h2>Profile</h2>
        <hr>
        <div class="row">
          <div class="col-sm-7">
            <div class="row w-100 p-2">
              <label for="file" class="form-label font-weight-bold h6">Profile Image</label> <br>
              <span>Images must be in an .jpg, .jpeg, and .png format. All profile images will be resized to 400x400 pixels. No copyrighted or NSFW images allowed. </span>
              <input type="file" name="file" class="form-control file"  id="file">
              <div id="imgFeedback" class="invalid-feedback"></div>
              <button class="btn btn-primary" type="submit" id="uploadProfileSubmit" name="uploadProfileSubmit">Submit</button>
            </div>
            <div class="row w-100 p-2">
              <label for="file" class="form-label font-weight-bold h6">Remove Image</label> <br>
              <span>You can remove this picture by clicking the button below. You will be given an default picture as your profile, unless a new image is submitted.</span>
              <button class="btn btn-primary" type="submit" id="deleteProfileSubmit" name="deleteProfileSubmit">Remove</button>
            </div>
          </div>
        </div>
      </form> 

profileSettings.inc.php:

<?php
print_r($_POST);
if(isset($_POST["uploadProfileSubmit"])){
    $userID = $_POST['userID'];
    $file = $_FILES['file'];

    require $_SERVER['DOCUMENT_ROOT'].'/config/dbh.inc.php';
    require $_SERVER['DOCUMENT_ROOT'].'/includes/functions.inc.php';

    $uploadError = false;
    if(!empty($file['name']) && !empty($file['type']) && $file['size'] != 0){
        $errorFile = incorrectImgFile($file);
        if($errorFile !== false){
            $uploadError = true;
            $errorMsg = $errorFile;
        } else {
            moveFile($file);
            $imgName = $file['name'];
        }
    }else {
        $imgName = imgNameDB($conn, $userID);
    }

    if($uploadError !== true){
        //updateProfileImg($conn, $userID, $imgName)
        echo "success";
    }

 } else {
    echo "failed?";
 }

?>

任何人都知道我在通过 ajax 传递数据时做错了什么。提前致谢!

更新: 根据使用 FormData 的建议,我更新了 javascript 代码如下:

  $("form#profileForm").submit(function(event){
    event.preventDefault();
    var formData = new FormData($("form#profileForm")[0]);
    var file = $("form#profileForm")[0].files;
    var userID = $("input[type=hidden][name=userID]").val();
    var uploadProfileSubmit = $('button[name=uploadProfileSubmit]').val();
    var formData = new FormData();
    formData.append("file", file);
    formData.append("userID", userID);
    formData.append("uploadProfileSubmit", uploadProfileSubmit);
    $.ajax({
      url: 'includes/profileSettings.inc.php',
      data: formData,
      processData: false,
      contentType: false,
      enctype: 'multipart/form-data',
      type: 'POST'
      }).done(function(data){
        $("#settings-msg").html(data);
        alert(data);
    });
  });

2021 年 2 月 3 日更新: 使用 formData 时,$_FILES['file'] 不存在,但 $_POST['file'] 存在并且 [file] 未定义。如何传递文件以便我可以在 php 服务器端使用 $_FILES['file'] 获取数据?

只需使用 data : new FormData(this) 它会自动将所有值与 $_POST 和 $_FILES

一起传递