东莞网站建设设计,通过信息系统融合和创新形成企业解决方案,商城英文,宿州专业网站建设公司简介
最近遇到一个下载文件的需求#xff0c;因为文件不在本系统#xff0c;可以直接请求远程的加载接口#xff0c;不想通过本系统的后端再转一次。
于是就想通过前端JavaScript直接下载。
下面介绍2种方式。
通过模拟form表单提交
function downloadRemoteFile(url,m…简介
最近遇到一个下载文件的需求因为文件不在本系统可以直接请求远程的加载接口不想通过本系统的后端再转一次。
于是就想通过前端JavaScript直接下载。
下面介绍2种方式。
通过模拟form表单提交
function downloadRemoteFile(url,materialId) {var body document.getElementsByTagName(body)[0];var form document.createElement(form);form.method POST;form.action url;var param document.createElement(input);param.type hidden;param.name materialId;param.value materialId;form.appendChild(param);body.appendChild(form);form.submit();body.removeChild(form);
}上面这种方式
优点是简单缺点是错误不友好出错了没有提示信息
如果希望错误信息友好一点可以通过XMLHttpRequest方式。
通过XMLHttpRequest方式
function downloadRemoteFileXMLHttpRequest(url,materialId) {console.log(${downloadUrl} materialId);var xhr new XMLHttpRequest();xhr.open(POST, url, true);xhr.setRequestHeader(Content-Type, application/x-www-form-urlencoded)xhr.onload function () {if (xhr.status 200) {if (xhr.response null || xhr.response || xhr.response undefined) {alert(下载文件出错,请检查文件是否存在: materialId);return;}// 获取判断Content-Type// var contentType xhr.getResponseHeader(Content-Type);var blob new Blob([xhr.response], { type: application/octet-stream });var fileName getFileNameFromResponseHeader(xhr);var link document.createElement(a);link.href window.URL.createObjectURL(blob);link.download fileName;link.click();link.remove();window.URL.revokeObjectURL(link.href);} else {alert(下载响应异常);console.log(xhr);}};xhr.send(materialId materialId);
}function getFileNameFromResponseHeader(xhr) {var contentDisposition xhr.getResponseHeader(content-disposition)var matchResult /filename[^;\n]*(([]).*?\2|[^;\n]*)/.exec(contentDisposition);if (matchResult ! null matchResult[1]) {return decodeURIComponent(matchResult[1].replace(/[]/g, ));}return default-name;
}通过XMLHttpRequest方式就灵活很多虽然还是模拟了a链接但是能先处理响应。
例如下载后端可以能有一些预检查如果预检查都没有通过那么可能返回的就不是Blob文件而是一个json。
通过XMLHttpRequest方式就可以通过判断ContentType内容来获取文件流、或是json的内容从而把错误信息比较友好的展示给用户。
对于后端下载接口可能更好的方式是把信息写到header中这样对于前端来说就能更好统一处理逻辑。
response.addHeader(success, false);
response.addHeader(message, URLEncoder.encode(该数据您无权下载, StandardCharsets.UTF_8));后端不同处理方式(仅仅演示实际操作最后统一逻辑)
RequestMapping(/download)
public void download(HttpServletResponse response, RequestParam(fid) Long fid) throws IOException {if (fid 0) {response.setContentType(application/json);PrintWriter writer response.getWriter();ResultVoid result ResultHelper.getFailResult(文件不存在);writer.write(JSON.toJSONString(result));return;}if (fid 100) {response.addHeader(success, false);String message 该数据您无权下载;response.addHeader(message, URLEncoder.encode(message, StandardCharsets.UTF_8));return;}try (FileInputStream fis new FileInputStream(F:\\tmp\\流动性季报统计表.xlsx);OutputStream os response.getOutputStream()) {String fileName URLEncoder.encode(流动性季报统计表.xlsx,StandardCharsets.UTF_8);response.reset();response.setContentType(application/octet-stream);response.setHeader(Content-Disposition, attachment;filename fileName);response.addHeader(success, true);IOUtils.copy(fis, os);}
}