How to send multipart/form-data form content by ajax (no jquery)?

Pass attribute in form {url:"",method:"",data:{...},callback:function(){}}

var ajax=function(){
  try{
    var xml       =new XMLHttpRequest();
    var args      =arguments;
    var context   =this;
    var multipart ="";

    xml.open(args[0].method,args[0].url,true);

    if(args[0].method.search(/post/i)!=-1){
      var boundary=Math.random().toString().substr(2);
      xml.setRequestHeader("content-type",
                  "multipart/form-data; charset=utf-8; boundary=" + boundary);
      for(var key in args[0].data){
        multipart += "--" + boundary
                   + "\r\nContent-Disposition: form-data; name=" + key
                   + "\r\nContent-type: application/octet-stream"
                   + "\r\n\r\n" + args[0].data[key] + "\r\n";
      }
      multipart += "--"+boundary+"--\r\n";
    }

    xml.onreadystatechange=function(){
      try{
        if(xml.readyState==4){
          context.txt=xml.responseText;
          context.xml=xml.responseXML;
          args[0].callback();
        }
      }
      catch(e){}
    }

    xml.send(multipart);
  }
  catch(e){}
}

If you want to get back response you can use this

var response={};
ajax.call(response,{...args...})

and you can retrieve all data by response.txt or response.xml

A bit late update

As for @Varun question about <input type="file"> uploads, this code can’t handle file uploads directly, in order to send files using this code, you need to perform preprocessing of the raw file data using File API to get non-binary streams (like base64 or any other bin2hex-like form).

But, since it’s a 2015 year, I can suggest to move from the construction of the multipart streams to something a bit more robust, like the FormData API.

Leave a Comment