大家都知道,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) } } }
upload_file.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’)来访问。