之前在做项目的时候遇到一个问题,主要是在下载excel的时候下载下来是一个错误的文件,现特将问题所在汇总出来,提醒自己注意。
背景:项目是采用前后端分离来进行设计,使用ajax请求后台,后台代码使用post请求,结果可以下载到本地是正常的,但是下载到客户端是错误的文件。
原因分析:
对于直接下载到服务器本地,不涉及到浏览器的问题,所以get、post请求都可以。
而对于下载到客户端的信息需要涉及到response的应用,会涉及到
Content-Type: application/vnd.ms-excel之类的修改,所以当请求为以下方式时需要特别注意:
1、使用ajax请求下载;
ajax函数的返回类型只有xml、text、json、html等类型,没有“流”类型,所以我们要实现ajax下载,不能够使用相应的ajax函数进行文件下载。但可以用js生成一个form,用这个form提交参数,并返回“流”类型的数据。在实现过程中,页面也没有进行刷新。var form=$("<form>");//定义一个form表单
form.attr("style","display:none");
form.attr("target","");
form.attr("method","post");
form.attr("action","exportData");
var input1=$("<input>");
input1.attr("type","hidden");
input1.attr("name","exportData");
input1.attr("value",(new Date()).getMilliseconds());
$("body").append(form);//将表单放置在web中
form.append(input1);
form.submit();//表单提交
2 post请求下载
post请求无法直接发送请求下载excel文档,是因为我们在后台改变了响应头的内容:
Content-Type: application/vnd.ms-excel
导致post请求无法识别这种消息头,导致无法直接下载。
解决方法:
改成使用form表单提交方式即可
/*===================post请求下载文件
* options:{
* url:'', //下载地址
* data:{name:value}, //要发送的数据
* method:'post'
* }
*/var postDownLoadFile = function (options) {
var config = $.extend(true, { method: 'post' }, options);
var $iframe = $('<iframe id="down-file-iframe" />');
var $form = $('<form target="down-file-iframe" method="' + config.method + '" />');
$form.attr('action', config.url);
for (var key in config.data) {
$form.append('<input type="hidden" name="' + key + '" value="' + config.data[key] + '" />');
}
$iframe.append($form);
$(document.body).append($iframe);
$form[0].submit();
$iframe.remove();
}
//导出
$("#btnExport_year").on('click',
function() {
var param={};
postDownLoadFile({
url:path + '/monthlyCollection/exportExcelDoc.json',
data:param,
method:'post'
});
});
参数直接放到param中就可以带到后台了,
后台再用request.getParameterNames(); 即可接受到参数
3get请求可以正常使用
最后该项目的解决方法为使用ajax来下载到服务器本地,然后返回一个url地址,通过这个地址的进行get请求下载,成功。
第一次写博客,写的不好忘多多见谅!