1

I've been trying to adapt file upload support to my AJAX post function. I'm not sure what I'm missing here?

function ajax_post(url,param)
{
 if (url.substr(0,11)=='javascript:') {result = 'Error: form submits to JavaScript function.\n\nFunction can not be processed when passed off by onsubmit event handler.';}
 else
 {
  var xhr = false;

  if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();}
  else if (window.ActiveXObject) {try {xhr = new ActiveXObject('Msxml2.XMLHTTP');} catch (e) {try {xhr = new ActiveXObject('Microsoft.XMLHTTP');} catch (e) {}}}

  if (!xhr) {var result = 'Error: your browser does not support AJAX.'; browser_upgrade_notice();}
  else 
  {
   xhr.open('POST',url,true);
   var f = document.getElementById(id_page).getElementsByTagName('form');
   for (var i=0;i<f.length;i++)
   {
    if (f[i].compareDocumentPosition(option.submit)==20)
    {
     f = f[i];
     break;
    }
   }
   var i = f.getElementsByTagName('input');
   var k = 0;
   for (var j=0;j<i.length;j++)
   {
    if (i[j].type=='file')
    {
     k++;
     break;
    }
   }

   if (k==0)
   {
    xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
    xhr.send(param);
   }
   else
   {
    xhr.setRequestHeader('Content-Type','multipart/form-data');
    xhr.setRequestHeader('Cache-Control','no-cache');
    xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');

    var fd = new FormData();

    var z = param.split('&');
    for (var j=0;j<z.length;j++)
    {
     var y = z[j].split('=');
     fd.append(y[0],y[1]);
    }

    for (var j=0;j<i.length;j++)
    {
     if (i[j].type=='file')
     {
      fd.append('file_'+j,i[j].files[0]);
     }
    }
    xhr.send(fd);
   }

   if (xhr.readyState==4)
   {
    var result = xhr.responseText;
   }
  }
 }

 return result;
}
John
  • 1
  • 13
  • 98
  • 177
  • 1
    For starters, do not set the Content-Type of a request where you are sending a FormData object as the payload. – Ray Nicholus Nov 26 '13 at 18:56
  • @RayNicholus Yeah, +1, removing the header after I fixed other code made a difference between working / not working. – John Nov 27 '13 at 11:41

3 Answers3

0

I forgot about onreadystatechange as the sites I was looking at decided to only do half-tutorials plus I was tired.

This will dynamically go through a form and also upload every single file upload.

EDIT: Added file input element multiple attribute support.

function ajax_post(url,param)
{
 if (url.substr(0,11)=='javascript:') {result = 'Error: form submits to JavaScript function.\n\nFunction can not be processed when passed off by onsubmit event handler.';}
 else
 {
  var xhr = false;

  if (window.XMLHttpRequest) {xhr = new XMLHttpRequest();}
  else if (window.ActiveXObject) {try {xhr = new ActiveXObject('Msxml2.XMLHTTP');} catch (e) {try {xhr = new ActiveXObject('Microsoft.XMLHTTP');} catch (e) {}}}

  if (!xhr) {var result = 'Error: your browser does not support AJAX.'; browser_upgrade_notice();}
  else 
  {
   xhr.open('POST',url,true);
   var f = document.getElementById(id_page).getElementsByTagName('form');
   for (var i=0;i<f.length;i++)
   {
    if (f[i].compareDocumentPosition(option.submit)==20)
    {
     f = f[i];
     break;
    }
   }
   var i = f.getElementsByTagName('input');
   var k = 0;
   for (var j=0;j<i.length;j++)
   {
    if (i[j].type=='file')
    {
     k++;
     break;
    }
   }

   if (k==0)
   {
    xhr.send(param);
   }
   else
   {
    var fd = new FormData();

    var z = param.split('&');
    for (var j=0;j<z.length;j++)
    {
     var y = z[j].split('=');
     fd.append(y[0],y[1]);
    }

    for (var j=0;j<i.length;j++)
    {
     if (i[j].type=='file')
     {
      for (var m=0;m<i[j].files.length;m++)
      {
       fd.append('file_'+j+m,i[j].files[m]);
      }
     }
    }
    xhr.send(fd);
   }

   xhr.onreadystatechange = function()
   {
    if (xhr.readyState==4)
    {
     var result = xhr.responseText;
     alert('result = '+result);
    }
   }
  }
 }

 return result;
}
John
  • 1
  • 13
  • 98
  • 177
-1

It's not possible through XHR. You have to create a hidden iFrame with the file upload form in it and submit that via javascript.

Ajax file upload

Community
  • 1
  • 1
olleicua
  • 2,039
  • 2
  • 21
  • 33
  • It is possible in XHR, in all browsers other than IE9 and older. – Ray Nicholus Nov 26 '13 at 18:55
  • Yeah, I don't deal with irrelevant browsers, IE9 and older are def irrelevant. I'm just trying to figure out what I missed. Also I didn't down-vote you though I will be honest "no you can't" "answers" are almost as bad as off-topic and "oh, just use jQuery". >__> – John Nov 26 '13 at 19:02
-1

You can try to send binary data instead of sending file to server.

Below URL can be helpful.

Posting File Input as FileReader Binary Data through AJAX Post

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data?redirectlocale=en-US&redirectslug=DOM%2FXMLHttpRequest%2FSending_and_Receiving_Binary_Data#section_3

Community
  • 1
  • 1
kwelsan
  • 1,229
  • 1
  • 7
  • 18