1、前端请求只做下载功能
javascript
function downloadDatas3() {
// 封装请求参数
let formData = new FormData();
formData.append('page', '1');
formData.append('rows', '10');
// 创建xhr对象
let xhr = new XMLHttpRequest();
xhr.open('POST', 'http://127.0.0.1:8080/getData');
// xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = 'blob';// 设置响应类型为blob,以便处理二进制数据
xhr.send(formData);
xhr.onload = function () {
if (this.status == 200) {
let blob = this.response;
let a = document.createElement('a');
let url = window.URL.createObjectURL(blob);
//获取文件名称
let fileName = decodeURI(xhr.getResponseHeader('Content-Disposition'));
//截取=字符串后面的内容
let str = fileName.match(/=(\S*)/)[1];
a.href = url; // 设置链接源
a.download = str; // 设置下载文件名
document.body.appendChild(a); // 将链接加入到DOM
a.click(); // 触发下载
a.remove(); // 删除链接
window.URL.revokeObjectURL(url); // 释放URL对象
}
}
xhr.onerror = function (event) {
alert('文件下载失败!');
}
}
2、前端请求下载失败,提示失败原因
javascript
function downloadDatas3() {
// 封装请求参数
let formData = new FormData();
formData.append('page', '1');
formData.append('rows', '10');
// 创建xhr对象
let xhr = new XMLHttpRequest();
xhr.open('POST', 'http://127.0.0.1:8080/getData');
// xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = 'blob';// 设置响应类型为blob,以便处理二进制数据
xhr.send(formData);
xhr.onload = function () {
if (this.status == 200) {
let blob = this.response;
// 根据type类型,区分是下载文件还是下载失败原因
if ('text/html' == blob.type) {
let fileReader = new FileReader(); //FileReader可以读取Blob内容
fileReader.readAsText(blob); //二进制转换成text
fileReader.onload = function () { //转换完成后,调用onload方法
let result = fileReader.result; //result 转换的结果
let data = JSON.parse(result);
alert(data.msg);
}
return;
}
let a = document.createElement('a');
let url = window.URL.createObjectURL(blob);
//获取文件名称
let fileName = decodeURI(xhr.getResponseHeader('Content-Disposition'));
//截取=字符串后面的内容
let str = fileName.match(/=(\S*)/)[1];
a.href = url; // 设置链接源
a.download = str; // 设置下载文件名
document.body.appendChild(a); // 将链接加入到DOM
a.click(); // 触发下载
a.remove(); // 删除链接
window.URL.revokeObjectURL(url); // 释放URL对象
}
}
xhr.onerror = function (event) {
alert('文件下载失败!');
}
}
后端处理逻辑
下载文件使用响应头为 Content-Type=application/octet-stream
下载文件失败,使用响应头为 Content-Type=text/html
前端根据不同的响应头类型,来区分是下载文件,还是失败原因。
java
@PostMapping("/getData")
public void getData(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> map = new HashMap<>();
try {
// 请求参数
String currPage = request.getParameter("page");
String pageSize = request.getParameter("rows");
// 下载文件
String fileName = "测试.xlsx";
// 设置服务器输出的编码为UTF-8
response.setCharacterEncoding("UTF-8");
// 设置response的Header
response.addHeader("Content-Type", "application/octet-stream");
response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
ServletOutputStream os = response.getOutputStream();
// 响应输出流
int len;
byte[] buffer = new byte[4096];
FileInputStream fis = new FileInputStream("/tmp/" + fileName);
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
os.flush();
}
os.close();
fis.close();
map.put("code", 200);
map.put("msg", "下载成功");
} catch (Exception e) {
log.error(e.getMessage(), e);
map.put("code", 500);
map.put("msg", "下载数据异常!");
} finally {
// 处理失败
if (200 != (int) map.get("code")) {
try {
String msg = JSON.toJSONString(map);
response.setContentType("text/html; charset=UTF-8");
ServletOutputStream os = response.getOutputStream();
os.write(msg.getBytes(StandardCharsets.UTF_8));
os.flush();
os.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
}