0

So I have a simple FormData object with which I am trying to upload a File, without having to do form submit. In HTML I have created a simple form with 1) a File Upload 2) another simple text input for proof of concept. Trying to use the jquery $.post function to achieve this. The PHP file PHP_SIMPLE_AJAX_IMAGE.php just spits back the data from the same sent image. HTML is::

<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 ;
?>

When I put the two lines alert( fd.get('input_file_n').name); alert( fd.get('simp_text_n')); I get the alerts with the correct filename, so the fd object is indeed grabbing onto the form data. however when I execute, in the console I get a big error.. something along the lines of: "Uncaught TypeError: Illegal invocation" at the line in the javascript where $.post(... ) is located.. what is wrong?

JS Error

7
  • Does this answer your question? How to send FormData objects with Ajax-requests in jQuery? Commented Aug 30, 2020 at 11:25
  • The short answer is that you cannot pass a FormData object; jQuery only allows plain objects or strings by default. See here: stackoverflow.com/questions/166221/… My recommendation is to use fetch() instead. Commented Aug 30, 2020 at 11:27
  • You still need a solution to this ? Commented Aug 30, 2020 at 11:56
  • @AlwaysHelping yes I still do.. I don't know if using $.ajax is the answer, or using just pure javascript ajax call.. Im not sure what to do.. Commented Aug 30, 2020 at 11:58
  • 1
    Ideally you want to use $.ajax if you are using jQuery. But fetch api can work too. Let me know Commented Aug 30, 2020 at 11:59

2 Answers 2

3

Follow below instruction:

  1. You should have an input with type file in your html part:
<input type="file" id="file_target">
  1. Add change event for file input
$('#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);
  });
});
  1. Add uploadFile function that can upload the file:

You can validate the file to be upload here

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
  });
}
  1. PHP script file
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
  }
}

If you need no ajax approach please see https://gist.github.com/taterbase/2688850

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot @MMDM, it is very clear the solution you suggested. The problem I was having was; while using simple js, between xhr.open() and xhr.send() I had xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'). When I commented that out, it worked very well. Just one more q'n, what are the 'k' and 'file' arguments in your line * $.each(this.files, function (k, file) {..} ;* Im a begineer. Thank you so much!
My pleasure. In jQuery foreach, you can check index and value of an array through first and second arguments. So k is the index and file is value of it.
1

You can simply fetch to send do post request to your backend php file.

The reason its not working for you is that $.post cannot handle formData object itself - hence why you are getting that error.

Using fetch with Post method

Live Demo:

$("#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>

Using $.ajax with post method

Live Demo:

$("#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>

2 Comments

THanks a lot @AlwaysHelping, yes this works. Your answer is correct, as is the one posted by MMDM. Thank you so much.. and nice bike! I'd buy you a few beers for your help ;)
@Madventures You are welcome. Happy to have helped you. Let me know if there is something you need help with.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.