同步上传
application/x-www-form-urlencode将post传入的数据键值对化
比如:
<input type="text" name="username" />
<input type="password" name="password" />
转换之后:
username=123&password=3553
所以form标签会有一个提交格式enctype,默认是x-www-form-urlencode。文件提交的时候传输的值的文件名(字符串,传的不是文件)。
<form action="server/upload.php" method="post" enctype="application/x-www-form-urlencode">
<input type="text" name="file" /><br />
<input type="file" name="file" /><br />
<input type="submit" value="上传" />
</form>
但是文件是不能以文本的形式上传的,唯一能让文件在互联网上传输的方式就是二进制的方式:(同步上传)
enctype="multipart/form-data"
要上传多张图片,就设置multiple即可,同时注意name要加上数组符号,让后台知道是多个的形式
<input type="file" name="file[]" multiple="multiple" />
异步上传
FormData()表单数据构造函数,大多数标签都是可以通过js构造函数实例出来的,包括form标签。
我们把form标签去掉,它就不再是表单了,而是一堆输入类型控件,提交按钮也就不再具备默认提交跳转的功能了
<input type="text" id="username" />
<input type="password" id="password" />
<input type="submit" id="submitBtn" value="提交">
oSubmitBtn.onclick = function(){
fd.append('Username', oUsername.value);
fd.append('Password', oPassword.value);
console.log(fd);
console.log('username:' + fd.get('Username'));
console.log('password:' + fd.get('Password'));
fd.set('Username', 'jackson');
console.log(fd.has('Password'));
fd.delete('Password');
console.log('password:' + fd.get('Password')); //null
}
打印出来fd是只有一个原型的空实例化对象,可以实现键值对的增删改查。

上传文件的控件还有一个files属性,可以获取到文件信息
<input type="file" id="file" multiple="" />
<input type="submit" id="submitBtn" value="上传" />
<ul class="progress-wrap"></ul>
oFile.onchange = function() {
console.log(oFile.files);
}

上传AJAX值的时候,会有一个upload.onprogress事件处理函数,处理上传进度的问题。
e.loaded是已下载的量,e.total是总量
步骤分析:
- 用files属性获取文件个数、文件名称、文件大小,用以限制传入图片的个数、大小、判断是否符合图片格式。
- 将错误信息添加到oProgressBar中,没有就生成进度条
- 用FormData()创建表单,将通过for循环获取的一个个文件添加到表单中
- 将表单进行AJAX异步上传,其中还要设置处理进度条的事件处理函数o.upload.onprogress,获取当前的进度条,将上传进度转换为宽度进行设置
var oFile = document.getElementById('file'),
oSubmitBtn = document.getElementById('submitBtn'),
oProgressWrap = document.getElementsByClassName('progress-wrap')[0];
fd = new FormData();
oFile.onchange = function(){
var files = oFile.files,
fileLen = files.length;
if (fileLen <= 0) {
console.log('您还没有选择图片');
return;
}
if (fileLen > 5) {
console.log('最多可同时上传5张图片');
return;
}
oProgressWrap.innerHTML = '';
var fileName = '',
fileSize = 0,
maxSize = 104857600,
fd = null,
errorInfo = '';
for (var i = 0; i < fileLen; i++) {
fileName = files[i].name;
fileSize = files[i].size;
if (!/\.(gif|jpg|jpeg|png)$/.test(fileName)) {
errorInfo = '『' + fileName + '』文件不是图片类型';
}
if (fileSize > maxSize) {
errorInfo = '『' + fileName + '』文件超过可上传大小';
}
var oProgressBar = document.createElement('li');
oProgressBar.className = 'progress-bar';
oProgressWrap.appendChild(oProgressBar);
if (errorInfo !== '') {
oProgressBar.innerHTML = '<span class="error-info">' + errorInfo + '</span>';
}else{
oProgressBar.innerHTML = '<div class="progress"></div>';
fd = new FormData();
// file是后端会告诉我们的变量名
fd.append('file', files[i]);
var o = window.XMLHttpRequest ?
new window.XMLHttpRequest() :
new ActiveXObject('Microsoft.XMLHTTP');
o.open('post', 'server/m_upload.php');
// 有闭包问题
(function(i){
o.upload.onprogress = function(e){
var e = e || window.event,
percent = e.loaded / e.total * 100 + '%',
thisProgressBar = oProgressWrap.getElementsByClassName('progress-bar')[i];
thisProgressBar.getElementsByClassName('progress')[0].style.width = percent;
console.log(percent)
}
})(i);
o.send(fd);
}
}
}