When I try to do what's mentioned in the title, my requests all work (nonce check passes, and server response 200 receveived, and server - script also working properly). My problem is that I cannot access the image file I upload on the server-side script; $_FILES is always empty. Although there are already a lot of posts about this on stack overflow, none of their solutions works for me.

My HTML (note that I don't use a form tag, but shouldn't be a problem) :

<input type='file' name='imageupload' id='image-for-upload'>
<button onclick="testAjax()">Launch AJAX Request</button>

My JavaScript :

function testAjax() {
  let uploadContainer = document.getElementById('image-for-upload');
  let file = uploadContainer.files[0];
  let data = new FormData();
  let xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
    } else {
  xhttp.open('POST', ajaxurl, true);

Note that I commented the setRequestHeader line out because, with it, the server returns a client error (404), and answers with "0". According to what I've found, this means that the server is not understanding the action hook. When removing the setRequestHeader, things worked properly (except for the concern of this question). When checking my HTTP Request Header of a sent request, I however can actuall see

Content-type: multipart/form-data; boundary=...

... so for that header it should be alright anyway.

My Server Script:

// Ajax script used for testing purposes
if (empty($_FILES['imageupload'])) {
  echo 'The file is not recognized!';
} else {
  //echo 'it is not working!';
  echo 'It is working!';

No matter what I do, I always get a 200 server response, echoing "The file is not recognized!". Help? (Please stick to vanilla js, I don't wanna code in jQuery).

P.S.: When I observe my HTTP request of my ajax request more precisely, I can see that below the following (first) part of it:

Content-Disposition: form-data; name="image"; filename="myImage.jpg"
Content-Type: image/jpeg

I get a quite long super-weird looking string of red filled dots and random types of characters, so maybe some encoding's not working properly? Or is this usual for request bodies sending images via the form data?

Also, when I use


...as the server's response in my server-side script, I get an associative array with the keys

[image] => undefined
[_ajax_nonce] => nonce
[action] => test_ajax

..when I fire the request without uploading a file in the browser.

When I upload a file into the browser and then fire the request, I get an associative array without the [image] => undefined element, only the latter two, so it seems like it's not considering my image when I uploaded one...?

1 Answer 1


Ok, after days and hours got it; my mistake was that I tried to access the uploaded image with the value of its name attribute, using:


Apparently, when you upload a file with the formData API, the key used to access your file is not the value of the name attribute of your input tag used for the upload anymore, but it gets overridden by the key you specified in your formdata of the respective element. Simply spoken, with:

<input type="file" name="imageupload" id="myElement"/>

In your HTML (name attribute actually becomes obsolete, you don't even need to specify it), and:


In your JavaScript, you actually access your file in PHP on the server-side via:


and NOT with:


Something else. If the script on your server-side is php, you should always specifiy files of a form data in this way in JavaScript:

data.append('image[]', file);

and NOT


As I wrote above. This however changes nothing on how you access your file(s) in PHP, just use the way I've explained above.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.