ajax上传文件以及实现上传进度条(转载)

做微信企业号的时候,在‘我的日志'功能模块里边需要添加一个上传文件的功能,并且要显示上传过程中的进度条和提交后的文件名列表,于是做了基于ajax的文件上传,UI用的是MUI框架,后台是TP框架

前端代码如下:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <script type="text/javascript" src="~/js/jquery.min.js"></script>
    <script type="text/javascript" src="~/mui/dist/js/mui.min.js"></script>
</head>
<body>
    <form enctype="multipart/form-data">
        <div>
            <div class="maven-form-file">
                <button type="button" class="mui-btn mui-btn-primary mui-icon mui-icon-plus maven-btn-file">选择文件</button>
                <input type="file" id="doc-form-file" multiple="multiple" />
                <div id="demo" class="mui-progressbar">
                    <span></span>
                </div>
                <div id="file-list">

                </div>
            </div>

            <input type="hidden" name="token" value='' />
            <input type="hidden" name="user_id" value='' />
            <input type="hidden" name="wecha_id" value='' />
            <div class="mui-button-row">
                <button type="submit" class="mui-btn mui-btn-primary">确认</button>
                <a href="javascript:history.back()" class="mui-btn mui-btn-danger">取消</a>
            </div>
        </div>
    </form>

    <script type="text/javascript">
        $(function () {
            // mui("#demo1").progressbar({progress:20}).show();

            $('#doc-form-file').on('change', function () {
                var fileNames = '';
                var formData = new FormData();

                formData.append("myfile", this.files[0]);
                if (this.files[0] == undefined) {
                    mui.alert('你没选文件', "提示", "确定");
                    return false;
                }

                var process = 0;

                mui("#demo")[0].style.visibility = 'visible';
                mui("#demo").progressbar({ progress: 10 }).show();

                $.ajax({
                    url: "/UploadFile/Upload",
                    type: "POST",
                    data: formData,
                    contentType: false,//必须false才会自动加上正确的Content-Type
                    processData: false,//必须false才会避开jQuery对 formdata 的默认处理
                    xhr: function () { //获取ajaxSettings中的xhr对象,为它的upload属性绑定progress事件的处理函数
                        myXhr = $.ajaxSettings.xhr();

                        if (myXhr.upload) { //检查upload属性是否存在
                            //绑定progress事件的回调函数
                            myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
                        }

                        return myXhr; //xhr对象返回给jQuery使用
                    },
                    success: function (data) {
                        mui("#demo")[0].style.visibility = 'hidden';

                        if (data.status == 1) {
                            fileNames = '<span class="mui-badge mui-badge-success">' + data.filename + '</span> <input type="hidden" name="files[]" value="' + data.id + '">';
                            $('#file-list').append(fileNames);
                        }

                        mui.alert(data.info, "提示", "确定");
                    },
                    error: function () {
                        mui.alert("上传失败!", "提示", "确定");
                    }
                });
            });

            function progressHandlingFunction(e) {
                var curr = e.loaded;
                var total = e.total;
                process = curr / total * 100;

                mui("#demo").progressbar().setProgress(process);
            }
    </script>
</body>
</html>

上传的时候用到FormData对象,将文件组装成一组用 XMLHttpRequest发送请求的键/值对。然后放到ajax的data里边,但是要给ajax设置参数

  • contentType: false,//必须false才会自动加上正确的Content-Type
  • processData: false,//必须false才会避开jQuery对 formdata 的默认处理

进度条的实现:
在ajax的xhr的回调函数里,给他的upload属性添加onprogress事件回调,在回调函数里添加进度条的样式,回调函数的e对象里边包含loaded属性(已上传的大小),和total属性(文件的总大小),通过这个比例计算进度。

原文链接