1.问题背景:
之前下载,我都是使用get方式,也就是window.open打开新的标签页的方式,当传递给服务器的下载参数过多的时候,地址栏就会变得特别丑陋。
想在React中使用POST方式下载文件,无奈在网上搜到的React相关的资料过少,把自己经过探索后成功实践的案例与你分享。
2.解决方案:
在React中使用ReactDOM创建临时form表单,自动提交。
3. 解决步骤:
相信大家都是从网上搜到的JQuery代码写的传统处理方式,如下:
var questiontype = $('#QuestionType').combobox('getValue');//得到题型名称
var form = $("
那么为了使用React,该如何改造这段代码呢?划重点的来了
3.1)方案一、首先在react组件的render函数里面建立一个隐藏的div ,例如:
3.2 ) 方案一、 用户在页面上触发下载按钮后,执行以下函数:在隐藏的div里面创建临时表单,获取表单,提交表单,在div节点卸载临时表单。
downloadDetailData=()=>{
var divElement= document.getElementById("downloadDiv");
var downloadUrl=`${apiBasePath}/api/xxxxx/downloadDetailData`;
var params=JSON.stringify({
key:'value'
})
ReactDOM.render(
,
divElement
)
ReactDOM.findDOMNode(divElement).querySelector('form').submit();
ReactDOM.unmountComponentAtNode(divElement);
}
3.3)方案二,以用于解决浏览器兼容问题
评论区有小伙伴(hzw29106)报告,说chrome和IE没有问题,360浏览器切换页面时会导致自动下载的问题,经过小伙伴实践已找到方法,已经在项目用到并已上线,暂没发现有浏览器兼容问题 。以下是另一种方法实现:
let formElement = document.createElement('form');
formElement.style.display = "display:none;";
formElement.method = 'post';
formElement.action = ${apiBasePath}/api/xxxxx/downloadDetailData;
formElement.target = 'callBackTarget';
let inputElement = document.createElement('input');
inputElement.type = 'hidden';
inputElement.name = "params" ;
inputElement.value = params;
formElement.appendChild(inputElement);
document.body.appendChild(formElement);
formElement.submit();
document.body.removeChild(formElement);
大家在使用方案二的时候,如果遇到问题,可以私信博友hzw29106或者私信博主我,感谢小伙伴无私的分享。
3.4)从服务器接收参数,并write文件流
怎么在服务器接收params参数,我就无需多言了吧,比如你用的是SpringMVC,那么 @RequestMapping(value = "/downloadDetailData", method = RequestMethod.POST)
参数 为(@RequestParam(value="params")String params, HttpServletRequest request, HttpServletResponse response) 就可以了。
将params转化为指定的对象类型,用google 的GSON工具类就可以了
Gson gson = new Gson();
MyBean bean = gson.fromJson(params, MyBean .class);
好了,打完收工,希望对你有益 。
欢迎关注我的微信公众号-搜索 “前端琅琊阁“ 即可
或者向我提问: