Javascript 如何通过ajax(没有jquery)发送multipart/form-data表单内容?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5933949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to send multipart/form-data form content by ajax (no jquery)?
提问by BreakPhreak
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:
我试图在不重新加载页面的情况下发送一些表单,并且我试图了解幕后细节,因此不使用任何 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>
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.
调用了upload_file(),但如果我做对了,则不会发送数据。请就发送数据的正确方式提出建议。
回答by excanoe
Pass attribute in form {url:"",method:"",data:{...},callback:function(){}}
在表单中传递属性 {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
并且您可以通过response.txt
或检索所有数据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 APIto get non-binary streams (like base64 or any other bin2hex-like form).
至于@Varun 关于<input type='file'>
上传的问题,此代码无法直接处理文件上传,为了使用此代码发送文件,您需要使用File API对原始文件数据进行预处理以获得非二进制流(如 base64 或任何其他类似 bin2hex 的形式)。
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.
但是,由于现在是 2015 年,我可以建议从多部分流的构建转向更强大的东西,比如FormData API。
回答by T.J. Crowder
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).
XMLHttpRequest
除了null
您传入的代码之外,您的代码看起来还不错send
。您需要传入一个包含要发送的数据的字符串(当然是正确编码的)。
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.
请注意,如果您想发送input[type=file]
字段引用的文件,则需要将其读入内存,唯一的方法是使用新的File API,该API尚未得到广泛支持。
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 swfuploadif the browser doesn't support the File API, and fall back to a normal form submission if the browser doesn't support Flash.
如果您尝试发送带有进度条的文件,您可以通过在支持 File API 的浏览器上发布您通过 File API 读取的文件块来实现,可能会退回到基于 Flash 的上传器,例如如果浏览器不支持 File API,则swfupload,如果浏览器不支持 Flash,则回退到正常的表单提交。
回答by test
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.
w 文件 API,您的 XMLHtth 尚未得到广泛支持。
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.
如果您在支持 File API 的浏览器上尝试 le API,也许回退到基于 Flash 的上传器 likpRequest 代码看起来不错,除了您传递给 send.e swfupload 的 null 如果浏览器不支持File API,如果浏览器不支持发送带有进度条的文件,则退回到正常的表单提交,您可以通过发布您通过 Fit Flash 阅读的块来实现。