通过ajax上传文件,需要用到一个html5新特性——FormData(兼容性:chrome,ff,IE9及以上)
这里不需要有一个显示的form标签,因为你的数据完全由FormData对象构建,所以html代码只需要有个input用来获取文件就可以了。
FormData顾名思义,就是用于存放Form的数据信息的类,它是一个不透明的类,对外只暴露一个append方法,一般只在XMLRequest的send()函数里面作为传入参数使用。所以不要想着调试的时候可以看到FormData里面的信息,各种序列化函数也无法获取其内部信息。
整套上传文件的思路是:
构建一个FormData->把文件DOM对象塞到FormData里面->send出去。
前端html代码:
<input type="file" id="fileObj"/>
<div id='loading'></div>
<button id="upload">上传</button>
这里不需要有一个显示的form标签,因为你的数据完全由FormData对象构建,所以html代码只需要有个input用来获取文件就可以了。
原生js代码:
var fd=new FormData();
fd.append("thefile", document.getElementById('fileObj').files[0]);
var xmlhttp = window.XMLHttpRequest || window.ActiveXObject;
var xhr = new xmlhttp();
if (xhr.upload) { //显示上传进度
xhr.upload.addEventListener("progress", function(e) {
document.getElementById('loading').innerHTML=e.loaded/e.total*100; //这里的e.loaded代表已经上传的字节数,e.total代表总共需要上传的字节数
}, false);
}
xhr.open('POST', 这里是你的url , true);
xhr.send(fd);
注意:这里加入:xhr.setRequestHeader("Content-Type" , "multipart/form-data" );的话,在chrome和ff中会无法发送数据。
var fd = new FormData();
var file = $('#thefile')[0].files[0];
fd.append("thefile", file);
$.ajax({
url: "你的url",
type: 'POST',
data: fd,
processData: false,//用来回避jquery对formdata的默认序列化,XMLHttpRequest会对其进行正确处理
contentType: false,//设为false才会获得正确的conten-Type
xhr: function() { //用以显示上传进度
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function(e) {
$('#loading').text(e.loaded/e.total*100);
}, false);
}
return xhr;
},
async: true
}).then(function(data) {
if (data.IsSuccessful == false) {
alert('上传失败');
} else {
alert('上传成功');
}
})
jquery从1.5开始就不对外暴露xhr了,因此我们需要在进行ajax请求的时候自己传入一个构造好了xhr来获取上传进度。