使用FromData通过XHR上传
使用ajax技术,能够以xhr的方式,实现无刷新的表单数据的提交和响应。但是这种方式仅仅能够传递一般的参数,也就是以字符串的形式传递key和value。
XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个”表单”.比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件。
FormData的详细介绍:https://developer.mozilla.org/zh-CN/docs/Web/API/FormData
XHR2是在html5之后出现的,不属于html5,但是一般支持html5的浏览器,都是支持xhr2的,是的,没错,除了IE10以下的版本,主流浏览器都支持html5和xhr2。
一般的表单异步提交
<form id="postForm" action="upload.php" method="post" onsubmit="javascript:return subfun();" enctype="application/x-www-form-urlencoded">
<p>用户名:<input type="text" name="username"></p>
<p>密 码:<input type="password" name="password"></p>
<p><input type="submit" value="登录"></p>
</form>
<script>
function subfun() {
$.ajax({
url : "upload.php",
type : "POST",
data : $( '#postForm').serialize(),
success : function(data) {
console.info(data);
},
error : function(data) {
console.warn(data);
}
});
return false;
}
</script>
FormData表单上传
<form id="uploadForm" enctype="multipart/form-data" onsubmit="return subfun();">
<p>标题: <input id="title" type="text"/></p>
<input id="file" type="file"/>
<button id="upload" type="submit">upload</button>
</form>
<div id="info"></div>
<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
function subfun() {
var fd = new FormData();
fd.append("title",$("#title").val());
fd.append("file",$("#file")[0].files[0]);
$.ajax({
url: 'upload.php',
type: 'POST',
cache: false,
data: fd,
processData: false,
contentType: false
}).done(function(res) {
$("#info").text(res);
}).fail(function(res) {
$("#info").text(res);
});
return false;
}
</script>
FormData是可以存放form数据的容器,可以使用append方法,向容器中添加数据。
使用jquery的ajax方式发送FormData格式数据,需要2.0以上版本jquery。
我们也可以直接使用XHR对象发送FormData
<form id="uploadForm" enctype="multipart/form-data" onsubmit="return subfun();">
<p>标题: <input id="title" type="text"/></p>
<input id="file" type="file"/>
<button id="upload" type="submit">upload</button>
</form>
<div id="info"></div>
<script src="http://apps.bdimg.com/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
function subfun() {
var fd = new FormData();
fd.append("title",$("#title").val());
fd.append("file",$("#file")[0].files[0]);
var xhr = new XMLHttpRequest();
xhr.open("POST" ,"upload.php" , true);
xhr.send(fd);
xhr.onload = function(e) {
if (this.status == 200) {
document.getElementsById("info").innerText = this.responseText;
}
};
return false;
}
</script>
IE浏览器从IE7开始,内建 XMLHttpRequest 对象,但是从IE10开始,才支持HTML5,所以无论是jquery还是XMLHttpRequest对象的方法,都没法再IE10以下的浏览器工作。
upload.php
<?php
print_r($_POST);
print_r($_FILES);
将form指向页内iframe上传
前台表单页面
<form id="uploadForm" enctype="multipart/form-data" method="post" action="upload.php" target="hideIframe">
<p>标题: <input id="title" type="text" name="title"/></p>
<input id="file" type="file" name="file"/>
<button id="upload" type="submit">upload</button>
</form>
<div id="info" style="margin-top: 30px;"></div>
<iframe name="hideIframe" src="" style="display: none"></iframe>
<script>
function upload_display(msg) {
document.getElementById("info").innerText = msg;
}
</script>
后台数据处理页面
<?php
ob_start();
echo $_POST['title'];
echo $_FILES['file']['name'];
$msg = ob_get_clean();
echo "<script>parent.upload_display('".$msg."');</script>";
通过设置form的target属性为页面隐藏iframe名,将后台处理页面结果显示在iframe中,因为iframe隐藏,所以看不到输出。
然后在处理页面通过在iframe框架中执行parent.upload_display,调用页面中的upload_display函数,通过函数的传参数,将返回数据的结果进行显示。
兼容以上两种方式的无刷新上传
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多文件上传实例</title>
<script src="http://apps.bdimg.com/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
function xhrFun() {
if(typeof FormData == 'undefined') {
document.getElementById("uploadForm").setAttribute("target", "hideIframe");
document.getElementById("uploadForm").submit();
}else{
var fd = new FormData();
fd.append("title",$("#title").val());
fd.append("file",$("#file")[0].files[0]);
var xhr = new XMLHttpRequest();
xhr.open("POST" ,"upload.php" , true);
xhr.send(fd);
xhr.onload = function(e) {
if (this.status == 200) {
callbackFun(this.responseText);
}
};
}
}
//返回结果的展示
function callbackFun(msg) {
document.getElementById("info").innerText = msg;
}
//读取iframe中body的数据并显示
function iframeLoad() {
if(typeof FormData == 'undefined') {
var doc = document.getElementById("hideIframe").contentWindow.document;
var docRoot = doc.body? doc.body : doc.documentElement;
var msg = docRoot? docRoot.innerText : '';
callbackFun(msg);
}
}
</script>
</head>
<body>
<form id="uploadForm" enctype="multipart/form-data" action="upload.php" method="post" target="hideIframe">
<p>标题: <input id="title" type="text"/></p>
<p><input id="file" type="file"/></p>
<p>
<button id="upload" onclick="xhrFun()">确定</button>
</p>
</form>
<div id="info"></div>
</body>
<iframe name="hideIframe" src="" style="display: none" onload="iframeLoad()"></iframe>
</html>
upload.php
<?php
$msg = "处理完成";
echo $msg;
有点不舒服,明天再优化下吧,睡觉~~
参考文章: