开发者

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

I am trying to send some form without reloading the page and I am trying to understand the under-the-hood details therefore not using any JavaScript library:

var http = createRequestObject();
function createRequestObject() {
    var objAjax;
    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
        objAjax=new XMLHttpRequest();
    }
    else
    {// code for IE6, IE5
        objAjax=new ActiveXObject("Microsoft.XMLHTTP");
    }
    return objAjax;
}

function display_progress() { ... }    

function upload_file() {
    var request = 'UploaderServlet';
    http.open('post', request);
    http.onreadystatechange = display_progress;
    http.send(null); // HERE PROBABLY THE DATA SHOULD BE SENT
}

<form enctype="multipart/开发者_如何学编程form-data" id="upload_form" name="upload_form" method="POST" action="UploaderServlet" onsubmit="upload_file(); return false;" target="upload_target">
Choose a file <br />  
<input name="file" size="27" type="file" id="file" /> <br/> 
<input type="submit" name="uploadSubmitButton" value="Upload" /><br /> 
<br />  
</form> 

<iframe id="upload_target" name="upload_target" src="#" style="width:0;height:0;border:0px solid #fff;"></iframe>

The upload_file() is called, but if I get it right, the data is not sent. Please advice regarding the correct way to send the data.


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.


Your XMLHttpRequest code looks fine other than the null you're passing into send. You need to pass in a string containing the data to send (properly encoded, of course).

Note that if you want to send the file referenced by your input[type=file] field, you'll need to read it into memory, and the only way to do that is to use the new File API, which isn't broadly-supported yet.

If you're trying to send a file with a progress bar, you could do that by posting blocks of it you've read via the File API on a browser that supports the File API, perhaps fall back to a Flash-based uploader like swfupload if the browser doesn't support the File API, and fall back to a normal form submission if the browser doesn't support Flash.


need to pass in a string containing the data to send (properly encoded, of course).

w File API, whicYour XMLHtth isn't broadly-supported yet.

If you're trying le API on a browser that supports the File API, perhaps fall back to a Flash-based uploader likpRequest code looks fine other than the null you're passing into send.e swfupload if the browser doesn't support the File API, and fall back to a normal form submission if the browser doesn't supporto send a file with a progress bar, you could do that by posting blocks ofYou it you've read via the Fit Flash.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜