众所周知ajax是使用了浏览器内部的XmlHttpRequest对象来传输XML数据的。既然是Xml的数据传输,那么传输的数据肯定是文本的,而文件上传则需要传输二进制的数据,显然用ajax是不可能的。
这里要说的是用ajax上传文件其实只是类似ajax的那种操作,实际上并没有用到xmlhttprequest对象,对于用户来说是不管使用的什么技术,他们要的是流程简便。客户有个需求是需要在表单操作时点击浏览文件后判断文件是否合法,以及其是否超过上传的限制大小,并且要考虑到不同浏览器兼容。开始准备找javascript 的html object{input{file}}对象,发现没有兼容的对象,于是被迫使用伪ajax。
我的思路和方法是:
- 添加一个隐藏的iframe和ajax_callback函数
- 当用户行为触发时改变form的action值并且target到隐藏的iframe
- iframe中的伪ajax处理结束后调用parent.ajax_callback来处理结果
- 在ajax_callback中还原form的原始action值和target值
example:
html code:sample.html
<script type="text/javascript" language="javascript" src="check_file.js"></script>
< form name="upfile_form" action="request.PHP?act=upload" method="POST" enctype="multipart/form-data">
< p>input file title:
<input type="text" name="file_title" />
< /p>
< p>select less than 200K file:
<input type="file" name="upload_file" id="upload_file" onchange="checkFileSize(this);" />
< /p>
< p>
<input type="submit" value="submit" />
< /p>
<iframe name="check_file_frame" style="display:none;"></iframe>
< /form>
< form name="upfile_form" action="request.PHP?act=upload" method="POST" enctype="multipart/form-data">
< p>input file title:
<input type="text" name="file_title" />
< /p>
< p>select less than 200K file:
<input type="file" name="upload_file" id="upload_file" onchange="checkFileSize(this);" />
< /p>
< p>
<input type="submit" value="submit" />
< /p>
<iframe name="check_file_frame" style="display:none;"></iframe>
< /form>
js code:check_file.js
var fileForm = new Object();
function checkFileSize(fileObj) {
if(fileObj.value != "") {
var form = document.forms['upfile_form'];
//把form的原始数据缓存起来
fileForm.f = form;
fileForm.a = form.getAttribute("action"); //form.action 为一个静态的对象,所以这里要使用getAttribute方法取值
fileForm.t = form.target;
//请求服务器端
form.target = "check_file_frame";
form.action = "./ajax.PHP?act=upload";
//form.submit(); 其实上面的action已经会执行submit操作,这步可有可无
}
return false;
}
function ajax_callback(result) {
//还原form属性
fileForm.f.target = fileForm.t;
fileForm.f.setAttribute("action",fileForm.a);
//处理结果
switch(result) {
case 0:
alert("文件超过了200K或者没有选择文件,请重新上传!");
//todo somthing
default :
alert("合法");
//do somthing,如果你想使用这种方法实现真正的上传的话,那么在成功后把返回的文件路经存储在一个 input[hidden]里是个不错的办法
}
return ;
}
function checkFileSize(fileObj) {
if(fileObj.value != "") {
var form = document.forms['upfile_form'];
//把form的原始数据缓存起来
fileForm.f = form;
fileForm.a = form.getAttribute("action"); //form.action 为一个静态的对象,所以这里要使用getAttribute方法取值
fileForm.t = form.target;
//请求服务器端
form.target = "check_file_frame";
form.action = "./ajax.PHP?act=upload";
//form.submit(); 其实上面的action已经会执行submit操作,这步可有可无
}
return false;
}
function ajax_callback(result) {
//还原form属性
fileForm.f.target = fileForm.t;
fileForm.f.setAttribute("action",fileForm.a);
//处理结果
switch(result) {
case 0:
alert("文件超过了200K或者没有选择文件,请重新上传!");
//todo somthing
default :
alert("合法");
//do somthing,如果你想使用这种方法实现真正的上传的话,那么在成功后把返回的文件路经存储在一个 input[hidden]里是个不错的办法
}
return ;
}
<script type="text/javascript" language="javascript">
< ?PHP
if($_REQUEST['act'] == "upload") {
if(empty($_FILES['upload_file'])) {
die("parent.ajax_callback(0);");
}
if($_FILES['upload_file']['size'] > 200*1024) {
die("parent.ajax_callback(0);");
}
die("succeed");
}
?>
< /script>
< ?PHP
if($_REQUEST['act'] == "upload") {
if(empty($_FILES['upload_file'])) {
die("parent.ajax_callback(0);");
}
if($_FILES['upload_file']['size'] > 200*1024) {
die("parent.ajax_callback(0);");
}
die("succeed");
}
?>
< /script>
补充:Ajax下载文件
function download_file(url)
{
if(typeof(download_file.iframe)== "undefined")
{
var iframe = document.createElement("iframe");
download_file.iframe = iframe;
document.body.appendChild(download_file.iframe);
}
// alert(download_file.iframe);
download_file.iframe.src = url;
download_file.iframe.style.display = "none";
}