使用 Javascript FormData()、AJAX $.post 和 PHP 的简单文件上传

Posted

技术标签:

【中文标题】使用 Javascript FormData()、AJAX $.post 和 PHP 的简单文件上传【英文标题】:Simple file upload using Javascript FormData(), AJAX $.post and PHP 【发布时间】:2020-12-18 18:02:01 【问题描述】:

所以我有一个简单的 FormData 对象,我试图用它上传一个文件,而不必提交表单。 在 html 中,我创建了一个简单的表单,其中包含 1) 文件上传 2) 另一个简单的文本输入,用于概念证明。 尝试使用 jquery $.post 函数来实现这一点。 php 文件 PHP_SIMPLE_AJAX_IMAGE.php 只是从同一个发送的图像中吐回数据。 HTML 是::

<form id="form_image_upload">
    <input type="file" id="input_file" name="input_file_n"></input>
    <label for="input_file" id="label_input_file" >choose file</label>
    <label for="input_file" id="label_small_input_file">...</label><br>
    
    <input type="text" id='simp_text_id' name='simp_text_n' ><br>
    <button id="btn_submit" type="submit" value="submit" class="upload_file">Submit</button>
<form>

<DIV id="Sub_Div_7"> </DIV>

javascript

$("#input_file").change(function(e)
    $("#label_small_input_file").html(e.target.files[0].name);
    );

$("#form_image_upload").submit(function(e)
        e.preventDefault();
        let fd = new FormData(this);
    //  alert( fd.get('input_file_n').name);  //This works
    //  alert( fd.get('simp_text_n'));  //This works
        
    $.post("PHP/PHP_SIMPLE_AJAX_IMAGE.php", fd, function(data) 
                            $("#Sub_Div_7").html(data); );
);

PHP

<?PHP 
if(isset($_FILES['input_file_n'])
       $F_name = $_FILES['input_file_n']['name'];
        $F_tmpnm = $_FILES['input_file_n']['tmp_name'];
        $F_type = $_FILES['input_file_n']['type'];
        $F_size = $_FILES['input_file_n']['size'];      

$text_1 = isset($_POST['simp_text_n']) ? $_POST['simp_text_n'] : "NULL";
echo "Filename: " . $F_name . " Tempname: " . $F_tmpnm . " Type: ". $F_type  . " Size: " . $F_size . " TextInput: " . $text_1 ;
?>

当我把这两行放在 alert(fd.get('input_file_n').name);警报(fd.get('simp_text_n'));我收到了具有正确文件名的警报,因此 fd 对象确实在抓取表单数据。但是,当我执行时,在控制台中出现了一个大错误.. 类似于:“Uncaught TypeError: Illegal invocation”在 $.post(...) 所在的 javascript 行中.. 出了什么问题?

【问题讨论】:

这能回答你的问题吗? How to send FormData objects with Ajax-requests in jQuery? 简短的回答是你不能传递FormData 对象; jQuery 默认只允许普通对象或字符串。见这里:***.com/questions/166221/… 我的建议是改用fetch() 你还需要解决这个问题吗? @AlwaysHelping 是的,我仍然这样做.. 我不知道使用 $.ajax 是答案,还是只使用纯 javascript ajax 调用.. 我不知道该怎么做.. 如果您使用 jQuery,理想情况下您想使用 $.ajax。但是 fetch api 也可以工作。告诉我 【参考方案1】:

按照以下说明进行操作:

    您的 html 部分中应该有一个类型为 file 的输入:
<input type="file" id="file_target">
    为文件输入添加更改事件
$('#file_target').change(function (e) 
  e.preventDefault();

  // for single file upload
  uploadFile(this.files[0]);

  // for multiple file upload
  $.each(this.files, function (k, file) 
    uploadFile(file);
  );
);
    添加uploadFile可以上传文件的函数:

您可以在此处验证要上传的文件

function uploadFile(file) 
  // some validation like size or dimension
  //...

  var urlPath = 'php_script_file_for_upload';

  // create data to be send
  var fd = new FormData();
  fd.append('file_data', file);
  
  // if you do not want use jQuery
  var xhr = new XMLHttpRequest();
  // third parameter is set to be async request
  xhr.open('POST', urlPath, true);
  xhr.send(fd);

  // if you do use jQuery
  $.ajax(
    method: 'POST',
    url: urlPath,
    data: fd
  );

    PHP 脚本文件
if(!empty($_FILES['file_data']))
  
  $path = "uploads/";
  $path = $path . basename( $_FILES['file_data']['name']);

  if(move_uploaded_file($_FILES['file_data']['tmp_name'], $path)) 
    // successful upload
   else
    // error during upload
  

如果您不需要 ajax 方法,请参阅https://gist.github.com/taterbase/2688850

【讨论】:

非常感谢@MMDM,您建议的解决方案非常清楚。我遇到的问题是;在使用简单的 js 时,在 xhr.open() 和 xhr.send() 之间我有 xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')。当我评论它时,它工作得很好。还有一个 q'n,你的行中的 'k' 和 'file' 参数是什么 * $.each(this.files, function (k, file) .. ;* 我是初学者。非常感谢! 我的荣幸。在 jQuery foreach 中,您可以通过第一个和第二个参数检查数组的索引和值。所以k 是索引,file 是它的值。【参考方案2】:

您可以简单地fetch 发送发布请求到您的backend php 文件。

它对您不起作用的原因$.post 无法处理 formData 对象本身 - 因此您会收到该错误。

将fetch 与 Post 方法一起使用

现场演示:

$("#input_file").change(function(e) 
  $("#label_small_input_file").html(e.target.files[0].name);
);

$("#form_image_upload").submit(function(e) 
  e.preventDefault();
  let fd = new FormData($(this)[0]) //store data using $(this)[0]

  //Using Simple Fetch API
  fetch('PHP/PHP_SIMPLE_AJAX_IMAGE.php', 
      method: 'post',
      body: fd,
    )
    .then(function(data) 
      $("#Sub_Div_7").html(data);
    );
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form_image_upload">
  <input type="file" id="input_file" name="input_file_n" />
  <label for="input_file" id="label_input_file">choose file</label>
  <label for="input_file" id="label_small_input_file">...</label><br>

  <input type="text" id='simp_text_id' name='simp_text_n'><br>
  <button id="btn_submit" type="submit" value="submit" class="upload_file">Submit</button>
  <form>

<div id="Sub_Div_7"> </div>

使用 $.ajax 和 post 方法

现场演示:

$("#input_file").change(function(e) 
  $("#label_small_input_file").html(e.target.files[0].name);
);

$("#form_image_upload").submit(function(e) 
  e.preventDefault();
  let fd = new FormData($(this)[0])
  $.ajax(
    url: 'PHP/PHP_SIMPLE_AJAX_IMAGE.php',
    type: 'POST',
    data: fd,
    processData: false,
    contentType: false,
    success: function(data) 
      $("#Sub_Div_7").html(data);
    
  );
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form_image_upload">
  <input type="file" id="input_file" name="input_file_n" />
  <label for="input_file" id="label_input_file">choose file</label>
  <label for="input_file" id="label_small_input_file">...</label><br>

  <input type="text" id='simp_text_id' name='simp_text_n'><br>
  <button id="btn_submit" type="submit" value="submit" class="upload_file">Submit</button>
  <form>

<div id="Sub_Div_7"> </div>

【讨论】:

非常感谢@AlwaysHelping,是的,这行得通。您的答案是正确的,MMDM 发布的答案也是正确的。非常感谢……还有漂亮的自行车!我会为你买几瓶啤酒来帮助你;) @Madventures 欢迎您。很高兴能帮助到你。如果有什么需要帮助的,请告诉我。

以上是关于使用 Javascript FormData()、AJAX $.post 和 PHP 的简单文件上传的主要内容,如果未能解决你的问题,请参考以下文章

javascript 使用FormData创建GraphQL请求

javascript 通过jQuery Ajax使用FormData对象上传文件

在 javascript 中的 FormData 中发送文件列表

我可以在javascript中将数组附加到“formdata”吗?

JavaScript中 FormData 对象详解

从javascript函数创建的表单提交FormData到php