0

I have a form that passes various types of input to an ajax call, which opens a php script. The script will do various things including processing the file, before echoing an array of variables. All inputs go through $_POST regularly, and the file data is passed, too, but the file itself is not accessible from $_FILES.

I am not using jQuery, so most posts are hard to translate to my case. I have seen a similar issue here,https://stackoverflow.com/questions/56878395/files-empty-after-ajax-upload but that solution doesn't seem to apply.

Here are the key excerpts from the code, thank you in advance for any tips!

var ajaxResponse = "";
var qForm = document.getElementById('myForm');
qForm.addEventListener("submit", function(e) {
  e.preventDefault();
  var formData = new FormData(qForm);
  checkForm(formData);
  console.log(ajaxResponse); //this shows the $_FILES var_dump
});

function checkForm(formData) {
  var vars = "startDate=" + formData.get('startDate') +
    "&qInvited=" + formData.get('qInvited');
  ajaxRequestReturn("checkForm.php", vars);
}


function ajaxRequestReturn(phpRequest, vars) {
  var req = new XMLHttpRequest();
  req.open("POST", phpRequest, false); //not asynchronous, because I pass results to a global variable
  req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); //removing the setRequestHeader doesn't seem to make any difference.
  req.onload = function() {
    ajaxResponse = this.responseText;
  }
  req.onerror = function() {
    throw new Error("Bad request.");
  }
  req.send(vars);
  // form.submit();
}
<form class="loginForm" id="myForm" method="post" enctype="multipart/form-data" action="thisPage.php">
  <div>
    <input type="date" id="startDateInput" name="startDate">
  </div>

  <div>
    <input type="file" name="qInvited" required>
  </div>

  <input type="submit" id="submitBtn">
</form>

and the checkForm.php file is currently simply:

<?php
echo var_dump($_FILES);
?>

the var_dump($_FILES) should show the qInvited file in it, but it prints

array(0) {
}

instead.

3
  • Since you're uploading files via AJAX, you should probably use FormData(). Commented Jan 28, 2023 at 13:27
  • He is but not in a transparent manner var formData = new FormData(qForm); I suggest you look at other examples and have only ONE function handling the form. Right now it is not clear if you actually send the formdata to the server - I suspect the checkForm is not doing what you think it is doing Commented Jan 28, 2023 at 13:29
  • 1
    checkForm() transforms your data into some sort of query string (as well as your file). Why don't you directly send your object? Commented Jan 28, 2023 at 13:29

1 Answer 1

0

To upload a file via ajax you have to pass a FormData object in your call to XMLHttpRequest.send.
Get rid of the checkForm function and call ajaxRequestReturn with formData as the second parameter.
Also, application/x-www-form-urlencoded is not the correct content type(its multipart/form-data), remove that line. The correct content type will be set automatically when you use the FormData object.

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

1 Comment

Brilliant, it solved it in one go! I had started with the formData as argument, but it wouldn't work due to - I now understand - the wrong content type header in the ajax request, similar to the analogous question I was citing. Instead, I had first tried to simplify by using the checkForm function, and at that point removing the content header no longer was solving it. In short, I got tangled up in my own web of wrong fixes. Thank you all for the comments!

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.