TypeScript调用AJAX POST接口返回PDF无法打开Chrome内置阅读器怎么办
问题根源
你当前的实现有两处核心问题:
- 后端返回的响应头配置不符合触发Chrome内置PDF阅读器的要求
- 前端AJAX请求没有指定二进制响应类型,也没有对返回的PDF流做后续处理,浏览器不会自动识别并触发打开/下载行为
一、后端C#代码修改
调整响应头配置,适配PDF内置打开的要求:
[HttpPost] [ApplicationApiAuthorize("Administrator, ContentManager")] public IHttpActionResult PrintTemplates([FromBody] List<string> versionKeys) { var templates = versionKeys .Select(v => TemplatesDataService.GetTemplate(v)) .ToList(); var templateIds = templates.Select(b => b.Id).ToList(); var templateFile = TemplatesDataService.PrintTemplate(templateIds); var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(templateFile.Content) }; // 把Disposition类型从attachment改为inline,告诉浏览器优先内置打开资源而非直接下载 result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("inline") { FileName = templateFile.FileName }; // 把ContentType改为application/pdf,让浏览器识别资源类型为PDF,调用内置阅读器 result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); var response = ResponseMessage(result); return response; }
如果不需要内置打开、只需要触发自动下载,保留attachment配置即可
二、前端TypeScript代码修改
1. 调整Service层请求配置,指定响应类型为二进制blob
printItems(versionKeys: string[]): JQueryPromise<Blob> { return $.ajax({ type: "post", contentType: "application/json", data: JSON.stringify(versionKeys), url: this.apiUrls.PrintTemplates, // 新增配置,指定响应为二进制blob格式,避免jQuery默认转成文本导致乱码 xhrFields: { responseType: 'blob' } }); }
2. 补充请求成功后的流处理逻辑(按钮绑定的printItems方法所在的组件层)
// 按钮触发的打印方法 printItems() { // 这里替换成你实际的versionKeys参数 const versionKeys = ['key1', 'key2']; // 替换成你实际的service实例名 this.templateService.printItems(versionKeys).done(pdfBlob => { // 生成PDF的临时访问地址 const pdfTempUrl = URL.createObjectURL(pdfBlob); // 新窗口打开触发内置PDF阅读器 window.open(pdfTempUrl); // 10秒后释放临时URL资源,避免内存泄漏 setTimeout(() => { URL.revokeObjectURL(pdfTempUrl); }, 10000); // 如果你需要同时触发自动下载,补充下面这段代码即可 // const downloadLink = document.createElement('a'); // downloadLink.href = pdfTempUrl; // downloadLink.download = '打印模板.pdf'; // 可以替换成后端返回的文件名 // document.body.appendChild(downloadLink); // downloadLink.click(); // document.body.removeChild(downloadLink); }) }
如果浏览器拦截了window.open的弹窗,可以改用动态插入iframe的方式加载PDF地址,效果一致
内容的提问来源于stack exchange,提问作者Jefferson
相关产品推荐
相关产品推荐

