解决IE8下上传文件问题,无需flash,无需html5

解决IE8下上传文件问题

场景:实现上传文件功能,重写上传按钮样式,并需要得到后台返回的数据来动态修改页面。

要求:不需要flash以及其他额外需要的东西。

尝试过的方法:1.webuploader.js 2.uploadifive.js 3.纯原生 4.jquery.form.js

第一种:失败,webuploader需要安装flash才能生效。


<div class="fileUpload" id="fileInput" style="display: none">

    <span style="left: 35px;bottom: 1px;">

        <img class="jia" src="images/plus-solid.png"/>

    </span>

    <span style="right: 25px;bottom: 5px;">选择文件</span>

</div>


uploader = WebUploader.create({

        auto: true, // 是否自动上传

        swf: '/home/common/js/0.1.5-Uploader.swf',

        server: config.url() + "/upload",  // 上传接口

        pick: '#fileInput',

        // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!

        resize: false,

        fileSizeLimit: 50 * 1024 * 1024,

        fileNumLimit: 10,

        duplicate: true

    });

第二种:失败,需要支持html5


<div class="fileUpload" id="fileInput" style="display: none">

    <span style="left: 35px;bottom: 1px;">

        <img class="jia" src="images/plus-solid.png"/>

    </span>

    <span style="right: 25px;bottom: 5px;">选择文件</span>

</div>


$("#fileInput").uploadifive({

        //传输设置-------------------------------------------------------

        'uploadScript': '/upload',//定义服务器访问路径

        // 'fileObjName': 'fileData',//定义服务器接收参数名称

        // 'method': 'post',//上传文件的提交方法,取值'post'或'get'

        //'formData': { "imgType": "normal" }, //提交给服务器端的参数

        //'checkScript': '/Home/Check',//检查目标文件夹中是否存在与上载文件同名的文件

        'auto': true,//是否自动上传

        'multi': true,//是否允许多文件上传

        //样式-----------------------------------------------------------

        'buttonText': '<span style="left: 35px;bottom: 1px;"><img class="jia" src="images/plus-solid.png"/></span>\n' +

            '                                <span style="right: 25px;bottom: 5px;">选择文件</span>',//定义上传按钮显示的文字

        'buttonClass': 'fileUpload',//要添加按钮的样式

        'removeCompleted': false,//文件上传完毕后,是否从上传队列中移除

        'queueID': false,//指定用于显示上传队列的父级元素id

        //文件约束--------------------------------------------------------------

        'fileType': 'image/jpeg', //允许上传的文件类型。要允许所有设置为false,允许特定设置为['image/jpeg','video/*']

        'truncateLength': 0,//指定文件名称的截取长度,设置该值后,文件名称超过该长度将会被截取

        'fileSizeLimit': "200MB",//上传文件的大小限制 0则表示无限制

        'uploadLimit': 10,//指定允许上传的最大文件数量

        'simUploadLimit': 10, //一次可上传的文件数量

        'queueSizeLimit': 10,// 指定上传队列中一次可容纳的最大文件数量(定义上传队列约束)

        //'overrideEvents': [ 'onError'],//可指定多个插件默认事件中的事件名称,被指定的事件将不会执行

        //事件监听-----------------------------------------------------------

        //验证客户端浏览器兼容

        'onFallback': function () {

            layer.msg('浏览器不支持HTML5,无法上传!');

        },

        //验证客户端设定的约束

        'onError': function (errorType, file) {

            if (file != 0) {

                $("#file_upload").uploadifive("debug"); //在控制台输出调试信息

                var settings = $('#file_upload').data('uploadifive').settings;

                switch (errorType) {

                    case 'UPLOAD_LIMIT_EXCEEDED':

                        alert("上传的文件数量已经超出系统限制的" + settings.queueSizeLimit + "个文件!");

                        break;

                    case 'FILE_SIZE_LIMIT_EXCEEDED':

                        alert("文件 [" + file.name + "] 大小超出系统限制的" + $('#file_upload').uploadifive('settings', 'fileSizeLimit') + "大小!");

                        break;

                    case 'QUEUE_LIMIT_EXCEEDED':

                        alert("任务数量超出队列限制");

                        break;

                    case 'FORBIDDEN_FILE_TYPE':

                        alert("文件 [" + file.name + "] 类型不正确!");

                        break;

                    case '404_FILE_NOT_FOUND':

                        alert("文件未上传成功或服务器存放文件的文件夹不存在");

                        break;

                }

            }

        },

        //在每添加一个文件至上传队列时触发该事件

        'onSelect': function (queue) {

            console.log("被取消的文件数量:" + queue.cancelled);

            console.log("上传队列中的文件总数量:" + queue.count);

            console.log("上传错误的文件数量:" + queue.errors);

            console.log("被添加到上传队列中的文件数量:" + queue.queued);

            console.log("被替换的文件数量:" + queue.replaced);

            console.log("所选择的文件数量:" + queue.selected);

        },

        //在执行上传操作时触发(filesToUpload 需要上传的文件数)

        'onUpload': function (filesToUpload) {

            if (filesToUpload < 1) {

                alert("未选择任何文件");

                return false;

            }

        },

        //在上传每一个文件时触发(file:正在上载的文件对象)

        'onUploadFile': function (file) {},

        //在文件上传完成后触发

        'onUploadComplete': function (file, data) {

            if (data) {

                try {

                    data = JSON.parse(data);

                    if (data.result === true) {

                        alert(file.name+"上传成功");

                    } else {

                        alert(data.msg);

                    }

                } catch (e) {

                    alert(data);

                }

            }

        },

        //在上传被取消时触发

        'onCancel': function (file) {

            console.log('Test:' + file.name );

        }

    });

第三种:半成功,无法添加headers头,无法获得返回数据

重写样式过程中遇到的问题:

1.第一种方案,隐藏form表单,包括上传文件按钮。重新创建自定义按钮及其样式,然后通过模拟点击上传按钮实现。代码如下:


<form id="fileForm" method="post" action="/upload" enctype="multipart/form-data" style="display: none">

    <input type="file" name="file" value="上传文件" id="file"/>

</form>

<div class="fileUpload" id="fileInput">

    <span style="left: 35px;bottom: 1px;">

        <img class="jia" src="images/plus-solid.png"/>

    </span>

    <span style="right: 25px;bottom: 5px;">选择文件</span>

</div>


$("#fileInput").click(function (){

    $("#file").click();

})

$("#file").change(function() {

    $("fileForm").submit(); 

})

结果:上传按钮无效,修改关键代码如下:


$("#fileInput").click(function (){

    $("#file")[0].click();

})

结果:上传按钮有效,可选择文件,但是上传失败,无法成功上传文件。

经过测试:必须点击原本的文件上传,选择文件,再提交表单才能成功。不知道为什么,感觉我的IE8有毒。

关键代码修改如下:


<form id="fileForm" name="fileForm" action="" enctype="multipart/form-data" method="post">

    <input style="position:absolute;left: 0;top:0;width: 150px;height: 40px;cursor:pointer;font-size: 0;opacity:0;filter:Alpha(opacity=0);z-index:999;" name="file" type="file" value="上传" id="file1" accept="*/*"/>

    <a class="fileUpload" id="fileFormDiv" style="display: none">

        <span style="left: 35px;bottom: 0;"><img class="jia" src="/home/page/zjtzy/images/plus-solid.png"/></span>

        <span style="right: 25px;bottom: 5px;">选择文件</span>

    </a>

    <input type="submit" id="submitForm"/>

</form>

使用绝对定位,在原本上传按钮的位置,定义自己的按钮,并将原本的按钮透明度设置为0全透明,并置于最上层。这样看到的是我们自己定义的按钮,点击的却是原本的按钮。

这里又出现一个问题:按钮部分区域点击有效,部分无效。

经过测试:不管将原本的文件按钮高宽设置的多大,其按钮宽度永远不变,只有文件名称显示框会变长,高度则是都会变。

解决方法:设置文件框的font-size样式,将文字大小设置的越大,文件按钮也会变得更大。


<form id="fileForm" name="fileForm" action="" enctype="multipart/form-data" method="post">

    <input style="position:absolute;left: 0;top:0;width: 150px;height: 40px;cursor:pointer;font-size: 43px;opacity:0;filter:Alpha(opacity=0);z-index:999;" name="file" type="file" value="上传" id="file1" accept="*/*"/>

    <a class="fileUpload" id="fileFormDiv" style="display: none">

        <span style="left: 35px;bottom: 0;"><img class="jia" src="/home/page/zjtzy/images/plus-solid.png"/></span>

        <span style="right: 25px;bottom: 5px;">选择文件</span>

    </a>

    <input type="submit" id="submitForm"/>

</form>

第四种:成功,但是坑不少。

通过jquery.form.js的form.ajaxSubmit方法可以实现异步上传文件。

先放最终成功代码再说坑


<form id="fileForm" name="fileForm" action="" enctype="multipart/form-data" method="post">

    <input style="position:absolute;left: 0;top:0;width: 150px;height: 40px;cursor:pointer;font-size: 43px;opacity:0;filter:Alpha(opacity=0);z-index:999;" name="file" type="file" value="上传" id="file1" accept="*/*"/>

    <a class="fileUpload" id="fileFormDiv" style="display: none">

        <span style="left: 35px;bottom: 0;"><img class="jia" src="/home/page/zjtzy/images/plus-solid.png"/></span>

        <span style="right: 25px;bottom: 5px;">选择文件</span>

    </a>

</form>


var options = {

    url: '/upload',

    method: 'post',

    error: function(res){

        res = res.replace(/<pre[^>]*>/gi, "").replace(/<\/pre>/gi, '');

        res = eval('('+res+')');

        if(res.code===200){

            layer.msg("上传失败");

        }

    },

    success: function (res) {

        res = res.replace(/<pre[^>]*>/gi, "").replace(/<\/pre>/gi, '');

        res = eval('('+res+')');



        $("#fileForm").resetForm();

    }

};

$('#fileForm').ajaxSubmit(options);

第一个坑:我需要在请求种加上自己定义的headers头,但是无效,必须要设置iframe属性为false,headers才会成功加上。


var options = {

    url: '/upload',

    method: 'post',

    headers: {'token':'12345789'},

    iframe: false

};

$('#fileForm').ajaxSubmit(options);

第二个坑:只要将iframe设置为false,就无法上传文件,请求头中的contentType将会变成application/x-www-form-urlencoded; charset=UTF-8而不设置iframe属性就无法加headers头,不加iframe属性时contentType为multipart/form-data; boundary=---------------------------7e4d83512082a。

这里我很纠结,因为我不加headers,不在里面加token和sign后台就无法访问接口。但是测试了很久,这两个只能选一个,最后我后台放开这个接口,不进行拦截验证token和sign。

第三个坑:上传文件成功之后,返回的数据得不到,出现各种问题。

问题1:返回的数据为一张页面。

问题2:点击上传后,弹出下载文件窗口。

问题3:406错误。

这一切都源于数据类型不匹配。IE8不支持返回数据类型为application/json。

我试着修改后台代码,在@PostMapping中加上,produces = "text/plain;charset=utf-8",等不同的类型,最后就会出现上面三种错误。


@PostMapping(value = "uploadForIE", produces = "text/plain;charset=utf-8")

public HttpResult uploadForIE(@RequestBody MultipartFile file, String uuid, HttpServletRequest request){



}

最后的解决方法:通过jackson的ObjectMapper将后台返回数据转换成json字符串,再由前端将json字符串转换成对象。

这里还有最后一个坑,就是IE会自动给返回的数据加上<pre>这个标签,并把数据包起来,最后解决代码如下:


@PostMapping(value = "uploadForIE")

    public String uploadForIE(@RequestBody MultipartFile file, String uuid, HttpServletRequest request) throws JsonProcessingException {

        ObjectMapper mapper = new ObjectMapper();

        return mapper.writeValueAsString(upload(file, uuid, request));

    }


var options = {

    url: config.url()+'/uploadForIE?db_name='+getCookie('db_name'),

    method: 'post',

    error: function(res){

        res = res.replace(/<pre[^>]*>/gi, "").replace(/<\/pre>/gi, '');

        res = eval('('+res+')');

    },

    success: function (res) {

        res = res.replace(/<pre[^>]*>/gi, "").replace(/<\/pre>/gi, '');

        res = eval('('+res+')');

    }

};

$('#fileForm').ajaxSubmit(options);

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容