spring mvc 实现文件下载 (XMLHttpRequest Level2应用)

如何获取后台文件流,并弹出下载框?

前台:

1.模拟a标签的点击

function exportExcel(){
        var a = document.createElement("a");
        a.href = '/lowFareFind/exportExcel?token='+token;
        a.target = '_blank'; //新的标签页
        a.click(); //模拟点击并触发a标签默认行为     (使用jquery 方式click() 只会触发绑定的click函数行为,不会触发元素默认行为) ,如何触发默认行为?
    }


2.通过隐藏iframe

<iframe id="iframeFile" style="display:none"></iframe>
function exportExcel(){
        document.getElementById('iframeFile').src = '/lowFareFind/exportExcel?token='+token;
    }

注意 :需要设置X-Frame-Options HTTP响应头 值为 SAMEORIGIN , 默认为DENY (会拒绝引入资源到iframe中)

(Refused to display 'your url...' in a frame because it set 'X-Frame-Options' to 'DENY'.)

3.XMLHttpRequest Level 2 + iframe

XMLHttpRequest 2 支持了对流的获取操作,得到blob对象,使用URL.createObjectURL 获得对象URL

<iframe id="iframeFile" style="display:none"></iframe>
function exportExcel(){
        var oReq = new XMLHttpRequest();
        var url = '/lowFareFind/exportExcel?token='+token;
        oReq.open('get',url,true);
        oReq.responseType = 'blob';
        oReq.onload = function(e){
            if(oReq.status == 200)
                var blob = oReq.response;
                document.getElementById('iframeFile').src = window.URL.createObjectURL(blob); 
                console.log(blob);
        };
        oReq.send();
        
    }


后台

从redis中提取数据对象list,包装数据为Workbook对象并返回文件流

@RequestMapping("/exportExcel")
    public void exportExcel(@RequestParam("token") String token,HttpServletResponse response){
        try {
            String jsonStr = (String) redisTemplate.opsForHash().get(token, "ticketList");
            List<LowFareFindTicketVO> list = JSON.parseArray(jsonStr, LowFareFindTicketVO.class);
            Workbook workbook = lowFareFindExcelService.writeExcelFile(list);
            String fileName = IdGenerator.getTimestamp()+ "_比较后结果.xlsx";
            fileName = URLEncoder.encode(fileName,"utf-8");
            response.setHeader("Content-disposition","attachment; filename=" + fileName);
            response.setHeader("X-Frame-Options", "SAMEORIGIN");
            response.setContentType("application/msexcel");
            ServletOutputStream servletOut = response.getOutputStream();
            workbook.write(servletOut);
        } catch (Exception e){
            logger.error("#",e);
        }
    }

HTTP头 - response响应头属性设置

ContentType : 设置MIME类型   MIME类型解释

X-Frame-Options : 给浏览器指示允许一个页面可否在 <frame><iframe>或者 <object> 中展现的标记 ,网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击。 X-Frame-Options

Content-disposition : 消息头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。 Content-Dispostion

参考 MDN WEB DOCS

        XMLHttpRequest Level 2

        








猜你喜欢

转载自blog.csdn.net/zl_momomo/article/details/80801463