javascript XMLHttpRequest实现下载文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sunct/article/details/90106429

查阅网上关于JavaScript实现下载文件功能,主要有几种方式:

1. window.open(url)    这是最差劲最不负责任的做法,因为会下载会弹出白页面

2. 构造form表单,form.submit()    这种方式有一个问题:不能加入等待对话框

3. 使用XMLHttpRequest,获取response 实现下载, 但是有一个小问题:后台header中filename不能直接使用

以下针对第三种进行改进:

1. 前端代码

download: function(url, params, fileName) {
            var len, i = 0,
                temp, input, form, key;

            //处理参数
            var urlParams = [];
            if (isA(params)) {
                for (len = params.length; i < len; i++) {
                    temp = params[i];
                    urlParams.push(temp.key + "=" + temp.value);
                }
            } else if (isO(params)) {
                for (key in params) {
                    temp = params[key];
                    urlParams.push(key + "=" + temp);
                }
            } else if(isS(params)) {
                params = Utilities.parseQuery(params);
                for (key in params) {
                    temp = params[key];
                    urlParams.push(key + "=" + temp);
                }
            }

            //显示等待
            Dialogs.showWait('正在下载中,请稍候...');

            var xmlRequest = new XMLHttpRequest();
            xmlRequest.open("POST", url, true);
            xmlRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xmlRequest.responseType = "blob";
            xmlRequest.onload = function (oEvent) {
                if((xmlRequest.status >= 200 && xmlRequest.status < 300) || xmlRequest.status === 304) {
                    if(!fileName) {
                        //从header中获取
                        fileName = decodeURI(xmlRequest.getResponseHeader('filename'));
                    }

                    console.log(fileName);

                    //校验是否下载参数
                    var content = xmlRequest.response;
                    if(!fileName || fileName === 'null') {
                        var myReader = new FileReader();
                        myReader.addEventListener("loadend", function(e){
                            var msg = e.srcElement.result;
                            Dialogs.showWarn(msg);
                        });
                        myReader.readAsText(content);
                        return;
                    }

                    //数据转换为文件下载
                    var elink = document.createElement('a');
                    elink.download = fileName || 'demo.xlsx';
                    elink.style.display = 'none';
                    var blob = new Blob([content]);
                    elink.href = URL.createObjectURL(blob);
                    document.body.appendChild(elink);
                    elink.click();
                    document.body.removeChild(elink);

                    //关闭等待
                    Dialogs.hide();
                } else {
                    Dialogs.showWarn('下载失败');
                }
            };

            try {
                //发送参数字符串, 但是formData需要后台支持
                xmlRequest.send(urlParams.join('&'));
            } catch (e) {
                Dialogs.showWarn('发送下载请求失败');
                console.error('发送失败',e);
            }

        },

后台代码:

需要设置response.addHeader("filename", StringUtils.urlEncode(fileName + ".xlsx"));

@RequestMapping(value = "/download.json", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public String downloadList(
            RequestParamRequest requestParamRequest,
            HttpServletRequest request,
            HttpServletResponse response

    ) {

其他逻辑省略....

response.setContentType("application/octet-stream");
        response.addHeader("Content-disposition", "attachment; filename=" + new String((fileName + ".xlxs").getBytes("utf-8"), "ISO8859-1"));
        //在header中设置中文文件名,需要编码,前端需要获取
        response.addHeader("filename", StringUtils.urlEncode(fileName + ".xlsx"));

        OutputStream out = null;
        try {
            out = response.getOutputStream();
            workbook.write(out);
        } finally {
            IOUtils.closeQuietly(out);
        }
}

猜你喜欢

转载自blog.csdn.net/sunct/article/details/90106429