XMLHttpRequest Level 2 轻松Ajax上传:
- 记得在XMLHttpRequest Level 1时,实现ajax上传,就用隐藏的iframe实现,而且功能也受限。
- 有关XMLHttpRequest Level 2官方参考:http://www.w3.org/TR/XMLHttpRequest2/#the-open-method
- 在XMLHttpRequest Level 2中,可以轻松实现,下面以实例开始。
前端jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>第二代XmlHttpRequest异步上传</title>
<script type="text/javascript">
function upload(){
if (!window.FormData){
alert('您的浏览器不支持第二代XmlHttpRequest');
return;
}
// HTML5 新增对象
var formData = new FormData(document.getElementById('uploadForm'));
//添加其他表单域
formData.append('user', 'haolin');
formData.append('pass', '111111');
var xhr = new XMLHttpRequest();
xhr.open('POST', 'upload'); //请求url
//上传完成回调函数
xhr.onload = function(event) {
if (xhr.status === 200) {
alert("上传成功");
} else {
alert('出错了');
}
};
xhr.send(formData);
}
</script>
</head>
<body>
<h1>第二代XmlHttpRequest对象实现异步上传</h1>
<form id="uploadForm" action="" method="post" enctype="multipart/form-data">
<input id="upfile" type="file" name="upfile"/>
<input type="button" value="上传" onclick="upload()"/>
</form>
</body>
</html>
后端部分代码(基于apache commons upload):
PrintWriter out = new PrintWriter(response.getOutputStream());
FileItemFactory factory = new DiskFileItemFactory();// 为该请求创建一个DiskFileItemFactory对象,通过它来解析请求。执行解析后,所有的表单项目都保存在一个List中。
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items;
try {
items = upload.parseRequest(request);
Iterator<FileItem> itr = items.iterator();
while (itr.hasNext()) {
FileItem item = (FileItem) itr.next();
System.out.println("是否是FormField: " + item.isFormField());
System.out.println("接收到域: " + item.getFieldName());
System.out.println("接收到值: " + item.getString("utf-8"));
// 检查当前项目是普通表单项目还是上传文件。
if (item.isFormField()) {// 如果是普通表单项目,显示表单内容。
String fieldName = item.getFieldName();
out.println("the field name is " + fieldName);// 显示表单域名称。
} else {// 如果是上传文件,显示文件名。
out.println("the upload file name is " + item.getName());
}
}
out.flush();
out.close();
} catch (FileUploadException e) {
e.printStackTrace();
}
对上述Ajax上传进行了简单的封装:
var AjaxForm = function(cfg){
if (!window.FormData){
alert("Sorry, your browser doesn't supoort FormData!");
}
/**
* null or undefined 返回true, 否则false
*/
this.isNullOrUndefined = function(v, errMsg){
if (!v){
alert(errMsg);
return true;
}
return false;
};
var cfg = cfg || {};
if (this.isNullOrUndefined(cfg.id, "id can't be empty")) return;
if (this.isNullOrUndefined(cfg.url, "url can't be empty")) return;
this.id = cfg.id; // 表单id
this.method = cfg.method || "POST"; //默认POST方法
this.url = cfg.url;
this.async = !cfg.sync; //同步否
this.resultType = cfg.resultType || "text"; //返回结果类型 json对象或text
this.formData = new FormData(document.getElementById(this.id)); //form数据
this.xhr = new XMLHttpRequest(); //当前请求对象
/**
* 超时事件
* 配置格式:
* timeout : xxx,
* onTimeout: function(event){}
*/
if (cfg.timeout){
this.xhr.timeout = cfg.timeout;
this.xhr.ontimeout = cfg.onTimeout;
}
/**
* 发送过程事件
* 配置格式:
* onProgress: function(loaded, total){}
*/
if (cfg.onProgress){ //发送数据过程
this.xhr.upload.onprogress = function(e){
if (e.lengthComputable) {
cfg.onProgress(e.loaded, e.total);
}
};
}
/**
* 上传完成事件
*/
if (cfg.onComplete){
this.xhr.onload = function(event){
var res = event.target.responseText;
if (this.resultType === 'json'){
if ((typeof JSON) === 'undefine'){
res = eval("("+res+")");
} else{
res = JSON.parse(res);
}
}
cfg.onComplete(res);
};
}
/**
* 发出请求
*/
this.request = function(){
this.xhr.open(this.method, this.url, this.async);
this.xhr.send(this.formData);
};
};
调用实例:
var af = new AjaxForm({
id: "uploadForm",
url: 'upload',
method: 'POST',
timeout: 5000,
onTimeout: function(event){
alert('It is timeout.');
},
onProgress: function(loaded, total){
var complete = (loaded / total * 100 | 0);
var progress = document.getElementById('uploadProgress');
progress.value = complete;
progress.innerHTML = complete;
},
onComplete: function(result){
alert(result);
}
});
af.request();
不吝指正。
来源:oschina
链接:https://my.oschina.net/u/222173/blog/215472