使用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;
有点不舒服,明天再优化下吧,睡觉~~
参考文章: