【问题标题】:How to send multipart/form-data form content by ajax (no jquery)?如何通过 ajax(无 jquery)发送 multipart/form-data 表单内容?
【发布时间】:2011-08-21 11:52:28
【问题描述】:

我正在尝试在不重新加载页面的情况下发送一些表单,并且我正在尝试了解幕后细节,因此不使用任何 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>

upload_file() 被调用,但如果我做对了,数据就不会发送。请就发送数据的正确方式提出建议。

【问题讨论】:

    标签: javascript ajax


    【解决方案1】:

    需要传入一个包含要发送的数据的字符串(当然是正确编码的)。

    w 文件 API,您的 XMLHtth 尚未得到广泛支持。

    如果您在支持 File API 的浏览器上尝试 le API,可能会回退到基于 Flash 的上传器 likpRequest 代码看起来不错,除了您传递给 send.e swfupload 如果浏览器不'不支持 File API,如果浏览器不支持发送带有进度条的文件,则回退到正常的表单提交,您可以通过发布您已通过 Fit Flash 阅读的块来做到这一点。

    【讨论】:

      【解决方案2】:

      {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){}
      }
      

      如果你想得到回复,你可以使用这个

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

      您可以通过response.txtresponse.xml检索所有数据

      更新有点晚

      关于@Varun关于&lt;input type='file'&gt;上传的问题,此代码不能直接处理文件上传,为了使用此代码发送文件,您需要使用File API对原始文件数据进行预处理以获得非- 二进制流(如 base64 或任何其他类似 bin2hex 的形式)。

      但是,由于是 2015 年,我可以建议从多部分流的构建转向更强大的东西,例如 FormData API

      【讨论】:

      • 无法理解我们将在数据中为&lt;input type=file 提供什么
      【解决方案3】:

      除了您传递给sendnull 之外,您的XMLHttpRequest 代码看起来还不错。您需要传入一个包含要发送的数据的字符串(当然是正确编码的)。

      请注意,如果您想发送 input[type=file] 字段引用的文件,您需要将其读入内存,唯一的方法是使用新的 File API,这不是得到广泛支持。

      如果您尝试发送带有进度条的文件,您可以通过在支持 File API 的浏览器上发布您通过 File API 读取的文件块来做到这一点,也许回退到 Flash-如果浏览器不支持 File API,则基于上传器,如 swfupload,如果浏览器不支持 Flash,则回退到正常的表单提交。

      【讨论】:

      • 感谢您的快速答复。 johnboy.com/scripts/php-upload-progress-meter/progress.phps - YUI 以某种方式设法在没有 File API / flash 等的情况下成功发送表单数据。
      • @BreakPhreak:啊,是的,这是另一种方式,需要服务器端支持:您执行标准表单发布,然后(单独)轮询服务器询问到目前为止它收到了多少数据,并以这种方式显示进度指示器。但当然,这需要服务器端的支持。 (它还要求浏览器允许您在运行表单 POST 的同时进行 ajax 调用,但大多数都会这样做。)不过,如果您控制事务的双方,仍然很酷。
      • 首先,我确实为进度条提供了服务器端支持。我仍然无法了解数据是如何发送的。我的意思是,我查看了 YUI 源代码(yui.yahooapis.com/2.9.0/build/connection/connection_core-min.js",_setForm 函数),这看起来像是一场噩梦 :)
      • @BreakPhreak:他们正在 iframe 中提交表单,请参阅 github.com/yui/yui2/blob/master/src/connection/js/… 中的 uploadFile 函数。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多