先看一下最初的pdf文件下载代码:
@PostMapping(value = "/downPdf")
public void downPdf(HttpServletResponse response)throws Exception {
//获取要下载的模板名称
String fileName = "InstructionsPdf.pdf";
OutputStream os=null;
response.reset();
response.setCharacterEncoding("utf-8");
//通知客服文件的MIME类型
response.setContentType("application/pdf");
//设置要下载的文件的名称
response.setHeader("Content-disposition", "attachment;fileName=" + fileName);
//获取文件的路径
Resource resource = new ClassPathResource("/template/" + fileName);//改为你自己的路径
File sourceFile = resource.getFile();
try{
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(sourceFile));
byte[] b=new byte[bis.available()+1000];
int i=0;
os = response.getOutputStream(); //直接下载导出
while((i=bis.read(b))!=-1) {
os.write(b, 0, i);
}
os.flush();
os.close();
}catch(Exception e){
logger.error("错误信息:", e);
}finally {
os.close();
}
}
postman测试接口功能正常,所以开始前端调用
前端调用代码:
//下载pdf文件
const onPdfDown = () => {
request({
url: '/downPdf',
method: 'post',
responseType: 'blob',
}).then(res => {
console.log('PDFres',res);
var blob = new Blob([res], {
type: 'application/pdf;charset=UTF-8',
}); //type这里表示pdf类型
console.log('blob',blob);
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, '使用说明.pdf');
} else {
var downloadElement = document.createElement('a');
var href = window.URL.createObjectURL(blob); //创建下载的链接
downloadElement.href = href;
downloadElement.download = '使用说明.pdf'; //下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); //点击下载
document.body.removeChild(downloadElement); //下载完成移除元素
window.URL.revokeObjectURL(href); //释放掉blob对象
}
});
};
此时,问题出现了:
页面报错
后台报错:
org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。 at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:341) at org.apache.catalina.connector.OutputBuffer.appendByteArray(OutputBuffer.java:736) at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:665) at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:376) at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:354) at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96) at net.cnki.qa.custom.controller.apiservice.ApiManagerController.downloadQaApiPdf(ApiManagerController.java:261) at net.cnki.qa.custom.controller.apiservice.ApiManagerController$$FastClassBySpringCGLIB$$f46aa5a3.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) at net.cnki.qa.custom.controller.apiservice.ApiManagerController$$EnhancerBySpringCGLIB$$ca779564.downloadQaApiPdf(<generated>) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) .........
各种查找原因,最后发现,原来是目前的浏览器为了数据的安全,所有请求被严格限制在同一域名下,如果需要从不同的服务器(不同域名)上获取数据,那么需要使用跨域HTTP请求。
解决措施:
接口代码中给HttpServletResponse对象添加头信息
response.addHeader("Access-Control-Allow-Origin","*");
好了,前端按钮可以顺利的下载pdf文件喽