大家都知道,IE9对FileApI支持不友好,所以想做一个兼容IE9实现无刷新上传也并非易事,一般的解决方案都是对IE9使用Flash方式上传,对现代浏览器使用FileApI。百度的WebUploader就是采用的这种方式,不过我们今天要谈的是IE9下使用Iframe实现无刷新上传。
代码实现
其原理是利用form的target属性,将form的action在iframe中打开,并接收返回结果,实现仿ajax的页面无刷新文件上传。正是action在iframe中打开,所以页面才不会刷新。target属性值为iframe的name值。这种方式很早就有了,只是最近才用到项目中。
- CSS代码:
#uploadFrame, #upload{
display:none;
}
- Html代码:
<form action="upload_file.php" enctype="multipart/form-data" method="post" target="uploadFrame" id="uploadForm">
<input type="file" name="upload" id="upload" accept="image/*"/>
<label id="fileName" for="upload">请选择文件</label>
<button id="uploadBtn">上 传</button>
<p>
<img id="result">
</p>
<iframe id="uploadFrame" name="uploadFrame"></iframe>
</form>
- JS代码:
var uploadFrame = document.getElementById('uploadFrame');
// 监听frame的 onload方法
uploadFrame.onload = function () {
// 获取iframe里面的内容
var response = this.contentDocument.body.textContent;
// 上传完成后的处理
if (response) {
var data = JSON.parse(response)
if (data.code === '1') {
document.getElementById('result').src = data.src;
} else {
alert(data.message)
}
}
}
- PHP代码:
<?php
$response = array();
$file_name = $_FILES['upload']['name'];
if ($file_name) {
// 允许上传的图片后缀
$allowed_file_type = array('jpg', 'jpeg', 'png', 'gif');
// 允许上传的图片大小
$max_file_size = 2 * 1024 * 1024;
$file_size = $_FILES['upload']['size'];
$ext = pathinfo($file_name, PATHINFO_EXTENSION);
if (!in_array($ext, $allowed_file_type)) {
$response['code'] = '0';
$response['message'] = '文件只能是jpg,gif,png图片';
} elseif ($file_size > $max_file_size) {
$size = $max_file_size / (1024 * 1024);
$response['code'] = '0';
$response['message'] = '您上传的文件大小超出了' . $size . ' MB';
} else {
// 如果 upload 目录不存在该文件则将文件上传到 upload目录下
move_uploaded_file($_FILES['upload']['tmp_name'], 'upload/' . $file_name);
$response['code'] = '1';
$response['message'] = '上传成功';
$response['src'] = 'upload/' . $file_name;
}
} else {
$response['code'] = '0';
$response['message'] = '未选择图片';
}
echo json_encode($response);
注意
IE9及以下版本不能识别files属性;获取文件需要属性很麻烦,需要用户设置浏览器打开IE>工具 > Internet选项 > 安全 > 自定义级别 > 启用ActiveX
,开启跨域。再使用new ActiveXobject('Scripting.FileSystemObject')
来访问。
评论 (0)