如何通过ajax(没有jquery)发送multipart/form-data表单内容?

Bre*_*eak 15 javascript ajax

我试图发送一些表单而不重新加载页面,我试图理解引擎盖下的细节,因此不使用任何JavaScript库:

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>
Run Code Online (Sandbox Code Playgroud)

调用upload_file(),但如果我做对了,则不会发送数据.请告知有关发送数据的正确方法.

exc*_*noe 22

传递表单中的属性 {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){}
}
Run Code Online (Sandbox Code Playgroud)

如果您想获得回复,可以使用此功能

var response={};
ajax.call(response,{...args...})
Run Code Online (Sandbox Code Playgroud)

并且您可以通过response.txt或检索所有数据response.xml

有点晚更新

至于关于<input type='file'>上传的@Varun问题,此代码无法直接处理文件上传,为了使用此代码发送文件,您需要使用File API对原始文件数据进行预处理以获取非二进制流(如base64或任何其他类似bin2hex的形式).

但是,由于它是2015年,我可以建议从多部分流的构建转向更健壮的东西,比如FormData API.