天天看点

IE兼容笔记(一):兼容IE9表单上传文件

几年前做兼容IE8的pc端项目的时候就遇到文件上传的需求,当时也是查看文档来解决IE9以下不支持formData的问题。由于之前没有写博客的习惯,最近又遇到这样的需求,所以写出来想帮助需要用到的朋友。

本身文件上传不难,只需要注意一些细节:

  1. 用最初的表单提交的方式form.submit()
  2. <input type='file'> onchange问题
  3. 点击<input type='file'>问题
  4. 提交表单后跳转问题

一,用最初的表单提交的方式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中:

IE兼容笔记(一):兼容IE9表单上传文件

美化前谷歌中:

IE兼容笔记(一):兼容IE9表单上传文件

美化后:

IE兼容笔记(一):兼容IE9表单上传文件
IE兼容笔记(一):兼容IE9表单上传文件

可以看到美化后和一般的按钮没什么区别了。

四,提交表单后跳转问题

    正常提交表单后会跳转页面,有时候不希望跳转,则需要用一个隐藏的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。

继续阅读