几年前做兼容IE8的pc端项目的时候就遇到文件上传的需求,当时也是查看文档来解决IE9以下不支持formData的问题。由于之前没有写博客的习惯,最近又遇到这样的需求,所以写出来想帮助需要用到的朋友。
本身文件上传不难,只需要注意一些细节:
- 用最初的表单提交的方式form.submit()
- <input type='file'> onchange问题
- 点击<input type='file'>问题
- 提交表单后跳转问题
一,用最初的表单提交的方式form.submit()
在IE9中不支持formData对象,无法使用ajax上传文件,所以通过在一个form表单中直接提交到服务器上传。
<form>
<input type="file">
</form>
<button onclick="submit()">上传</button>
<script>
function submit() {
var form = document.forms[0]
form.submit()
}
</script>
注意:如果要获取file的内容,主流浏览器可以通过获取input对象e.files[0]拿到,在IE9以下由于安全策略的因素不支持直接获取,但是可以通过微软在IE浏览器下支持的ActiveXObject对本地文件进行操作(有关ActiveXObject对象的了解可以点击这里),例如可以像下面这样拿到文件大小:
<script>
var path = '' // 这里是你的文件路径
var fso = new ActiveXObject('Scripting.FileSystemObject')
var fileSize = fso.GetFile(path).size
console.log('文件大小是:', fileSize)
</script>
二,<input type='file'> onchange问题
有时候需要在选择完文件立马上传,这是可以在标签<input type='file'>上添加onchange事件来进行提交表单,但是如果之前选择了一个文件没有清空,那么onchange事件不会触发,所以这里需要在适当的地方对文件清空。例如:
<form>
<input type="file" onchange="submit()">
</form>
<script>
function submit() {
var form = document.forms[0]
form.submit()
form.reset() // 提交完进行重置form表单
}
</script>
三,点击<input type='file'>问题
这里有几个点注意:
- IE 9中只能提交用户通过标签点击选择的文件
- IE9,IE10和火狐无法点击button标签中的<input type='file'>
- 修改浏览器默认<input type='file'>的样式
IE9出于安全性考虑无法提交除用户通过标签点击选择的文件,但是其他主流浏览器可以这样选择并上传文件:
<form>
<input id="fileId" type="file">
</form>
<button onclick="select()">选择文件</button>
<script>
function select() {
var inputFile = document.getElementById('fileId')
inputFile.click()
}
</script>
上面这种方式在IE9中可以选择文件,但是提交表单不会成功。所以只能点击<input type='file'>标签来上传,由于浏览器默认的标签样式很丑,这里可以采取下面这样来修改达到美化的效果:
<style>
form>span {
display: inline-block;
border: 1px solid #aaa;
padding: 5px 15px;
overflow: hidden;
position: relative;
}
#fileId {
opacity: 0;
position: absolute;
top: 0;
right: 0; // 注意:这里不用left:0;的原因是IE的点击区域在右边,左边是输入区域
bottom: 0;
font-size: 30px; // 这里是为了把<input type='file'>的点击按钮撑大以完全覆盖父元素
}
</style>
<form>
<span>
<input id="fileId" type="file">
上传
</span>
<button>
<input id="fileId" type="file"> // 放在button里面在IE9,IE10和火狐有问题
上传
</button>
</form>
上面代码主要是通过把<input type='file'>标签放在一个span标签里面,然后隐藏input标签并给span添加样式(注意:<input type='file'>放在button标签里面在IE9,IE10和火狐中会有问题,外面用span标签包裹就好了),这里隐藏的<input type='file'>需要全部覆盖span标签,不然点击span的某些区域无法触发input的选择文件事件,下面是美化前后的对比:
美化前IE中:

美化前谷歌中:
美化后:
可以看到美化后和一般的按钮没什么区别了。
四,提交表单后跳转问题
正常提交表单后会跳转页面,有时候不希望跳转,则需要用一个隐藏的iframe来接受表单提交的结果。例如:
<form action='http://' method='post' target='targetIframe'>
<input type="file" onchange="submit()">
</form>
<iframe name='targetIframe' style="display: none;">
</iframe>
<script>
function submit() {
var form = document.forms[0]
form.submit()
form.reset() // 提交完进行重置form表单
}
</script>
上面主要是需要指定form的target属性与iframe的name一致,这样提交表单后不会刷新页面,并且在iframe的body中可以拿到返回的数据。
注意: 在IE9中如果返回的是json格式的数据不会被解析,这时会弹出提示框是否要下载。解决方法是后台修改response的content-type为text/plain或text/html。