背景:想设计点击导出按钮,用ajax请求后端,返回文件下载;但实现上一直可以正常访问后端,却只返回文件字符串,不跳转下载。
首先,先说结论,经过问题排查发现:Ajax不能实现文件下载功能
产生原因:ajax回调已经把response的数据傻瓜式的以字符串的方式解析,ajax请求只是个“字符型”的请求,即请求的内容是以文本类型存放的。文件的下载是以二进制形式进行的,虽然可以读取到返回的response,但只是读取而已,console.log可以打印出读取的字符串,但是无法执行下载的。
解决方式:
1、使用a
标签来完成(服务器文件地址下载)
优点:
- 不会跳转新页面,用户体验较好
- 存储的路径是相对路径,地址一般后端返回
- 可以自定义文件名
缺点:
- 有兼容性,download是h5新增属性,如果需要导出像txt,jpg等浏览器支持直接打开的文件是不会执行下载的,而是会直接打开。 这时候可以给a标签添加一个download属性 ,所以如果不考虑兼容性的前提下,为保证文件都能正常下载而不是直接打开,都加上download。
- 无法执行post请求导出前端信息
2、二进制流导出
前端请求获取二进制数据流=>后端根据前端请求,查询数据库并把查询结果转成二进制数据流。(注意:这里并不生成一个文件保存在服务器
)=>后端把二进制数据流返回给前端=>前端把二进制数据流转成URL
对象并赋值给<a/>
标签=>点击<a/>
标签实现下载
优点:
- 不去要服务器生成文件,也不需要将文件保存在服务器中,可以有效较少服务器资源的占用
缺点:
- 不通用,可能存在兼容性
3、window.open/windows.location.href
优点:
- 可以是其他
h5
标签,在标签上加点击事件即可,不存在兼容性问题
缺点:
- 用户体验可能没那么好,需要新开窗口下载文件,也不能指定文件名,有可能会被浏览器的安全机制拦截
- 无法执行post请求导出前端信息
4、form表单提交
优点:
- 不用跳转页面,对用户友好,不存在兼容性问题
缺点:
- 拿不到后端处理这个过程的时机,无法根据回调函数做交互以及进度提示
参考文章: