总结自极客学院ajax文件上传地址
所谓异步上传,就是对比传统的表单提交,实现一种页面局部刷新的功能。
传统的表单提交一般都是点击某个提交按钮,然后真个页面处于一种被锁定的状态,上传完成后,页面跳转到一个新的页面。而一部上传则是在整个上传过程中,页面都没有被阻塞,用户可以同时进行其他的交互操作,在上传完成后,在局部页面中给出提示信息,不对整个页面进行刷新。
关键操作:
<iframe name="ifm" style="display: none;">iframe>
<form action="/upload" enctype="multipart/form-data" method="post" target="ifm" onsubmit="loading(true)">
<label for="myfile">附件:label>
<input type="file" name="myfile" id="myfile" />
<input type="submit" class="btn btn-primary" value="异步上传" />
<span id="uptxt" style="display: none;">正在上传。。。span>
form>
<div id="flist" style="border:1px dotted darkgray;">div>
<script>
function uploadFinished(fileName) {
addToList(fileName);
loading(false);
}
function addToFlist(fname) {
var temp = [""
,fname, ""];
$("#flist").append(temp.join(""));
}
function loading(showloading) {
if (showloading) {
$("#uptxt").show();
} else {
$("#uptxt").hide();
}
}
script>
表单提交的时候,信息被提交到那个target指向的隐藏的iframe页面中,使得当前主页面不刷新,而普通的文件上传中,target为当前主页面,所以文件上传成功后,返回的信息就显示在了当前页面,使得页面被刷新。
提交表单后,iframe会给当前页面反馈一些信息,来提示当前的上传进度。
后端代码处理
var express = require('express');
var router = express.Router();
var multipart = require('connect-multiparty'); //加载中间件
var multipartMiddleWare = multipart(); //调用中间件的构造方法
var fs = require('fs');
router.post('/upload',multipartMiddleWare,function(req,res) {
//第一个参数:被请求资源的url,第二个参数:中间件对象,第三个参数:异步文件上传处理函数
var fpath = req.files.myfile.path;
var fileName = fpath.substr(fpath.lastIndexOf('\\') + 1); //获取临时文件的名称,返回给当前页面
setTimeout(function() {
var ret = ["];
res.send(ret.join(""));
},1000)
});
上传完成后,iframe要通知当前提交页面上传完成,并传递上传的文件名称,以便当前页面做一些后续的处理
iframe页面返回的时候,直接执行一段脚本。找到主页面即window.parent,调用这页面定义的一个函数,参数为当前上传的文件名称
关键操作:
创建formData对象,将要上传的文件放入formData中
创建xhr对象,发送请求
(formData是HTML5的一个新属性,类似于传统的表单,formData中可以加入各个表单项以及它们的值。)
<div class="container">
<div class="roe">
<div class="col-md-12">
<div>
<div class="input-group">
"file" id="myfile" />
div>
<div>
"button" class="btn btn-primary" onclick="upload()" value="异步上传" />
id="uptxt" style="display: none;">正在上传...
id="upprogress">
div>
div>
<div id="fileList" style="border: 1px dotted darkgray">div>
div>
div>
div>
<script>
var formdata = new FormData(); //创建一个formData对象
formdata.append('myfile',$('#myfile')[0].files[0]);
//创建xhr,然后初始化对象,将请求发送出去
var xhr = new XMLHttpRequest();
function upload() {
//创建formData对象,然后将我们想要上传的文件放到formData里
var xhr = new XMLHttpRequest();
//监听状态,实时响应
xhr.upload.onprogress = function(event) {
if(event.lengthComputable) {
var percent = Math.round(event.loaded * 100 / event.total);
console.log('%d%',percent);
$('#upprogress').text(percent);
}
};
//传输事件开始,当xhr对象执行了send之后,马上会触发这个事件
xhr.onloadstart = function(event) {
console.log('load start');
$('#upprogress').text('开始上传');
$('#stop').one('click',function() { //显示‘取消盛传’按钮
xhr.abort(); //取消事件
$(this).hide(); //隐藏取消按钮
});
loading(true);
};
//文件上传成功
xhr.onload = function(event) {
console.log('upload success');
$('#upprogress').text('上传成功');
console.log(xhr.responseText);
var ret = JSON.parse(xhr.responseText); //两返回的数据转换为json格式
addToList(ret.fname); //将文件名显示在文件列表
};
//文件上传失败
xhr.onerror = function(event) {
console.log('error');
$('#upprogress').text('上传失败');
};
//上传被取消
xhr.onabort = function(event) {
$('#upprogress').text('上传取消');
};
xhr.onloadend = function(event) {
console.log('load end');
loading(false);
};
xhr.open('POST','/upload3',true);
xhr.send(formdata);
}
function addToList(fname) {
var temp = [""
,fname,""];
$('#fileList').append(temp.join(""));
}
function loading(showloading) {
if(showloading) {
$('#uptxt').show();
$('#stop').show();
}else {
$('#uptxt').hide();
$('#stop').hide();
}
}
script>
后端代码处理
router.post('/upload3',multipartMiddleWare,function(req,res) {
console.log(req.files);
var fpath = req.files.myfile.path;
var fname = fpath.substr(fpath.lastIndexOf('\\') + 1);
res.json({fname: fname});
});