rest - Angular 6从rest api下载文件
问题描述
我有我的 REST API,我在其中放置了我的 pdf 文件,现在我希望我的 angular 应用程序通过我的网络浏览器单击下载它,但我得到了 HttpErrorResponse
“位置 0 处 JSON 中的意外标记 %”
“SyntaxError:JSON.parse 中位置 0↵ 处 JSON 中的意外标记 %(
这是我的终点
@GetMapping("/help/pdf2")
public ResponseEntity<InputStreamResource> getPdf2(){
Resource resource = new ClassPathResource("/pdf-sample.pdf");
long r = 0;
InputStream is=null;
try {
is = resource.getInputStream();
r = resource.contentLength();
} catch (IOException e) {
e.printStackTrace();
}
return ResponseEntity.ok().contentLength(r)
.contentType(MediaType.parseMediaType("application/pdf"))
.body(new InputStreamResource(is));
}
这是我的服务
getPdf() {
this.authKey = localStorage.getItem('jwt_token');
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/pdf',
'Authorization' : this.authKey,
responseType : 'blob',
Accept : 'application/pdf',
observe : 'response'
})
};
return this.http
.get("http://localhost:9989/api/download/help/pdf2", httpOptions);
}
和调用
this.downloadService.getPdf()
.subscribe((resultBlob: Blob) => {
var downloadURL = URL.createObjectURL(resultBlob);
window.open(downloadURL);});
解决方案
我以这种方式解决了这个问题(请注意,我已经合并了在堆栈溢出时找到的多个解决方案,但我找不到参考。请随时在评论中添加它们)。
在我的服务中,我有:
public getPDF(): Observable<Blob> {
//const options = { responseType: 'blob' }; there is no use of this
let uri = '/my/uri';
// this.http refers to HttpClient. Note here that you cannot use the generic get<Blob> as it does not compile: instead you "choose" the appropriate API in this way.
return this.http.get(uri, { responseType: 'blob' });
}
在组件中,我有(这是从多个答案合并的部分):
public showPDF(fileName: string): void {
this.myService.getPDF()
.subscribe(x => {
// It is necessary to create a new blob object with mime-type explicitly set
// otherwise only Chrome works like it should
var newBlob = new Blob([x], { type: "application/pdf" });
// IE doesn't allow using a blob object directly as link href
// instead it is necessary to use msSaveOrOpenBlob
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(newBlob, fileName);
return;
}
// For other browsers:
// Create a link pointing to the ObjectURL containing the blob.
const data = window.URL.createObjectURL(newBlob);
var link = document.createElement('a');
link.href = data;
link.download = fileName;
// this is necessary as link.click() does not work on the latest firefox
link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));
setTimeout(function () {
// For Firefox it is necessary to delay revoking the ObjectURL
window.URL.revokeObjectURL(data);
link.remove();
}, 100);
});
}
上面的代码适用于 IE、Edge、Chrome 和 Firefox。但是,我不太喜欢它,因为我的组件是用浏览器特定的东西拉出来的,这些东西肯定会随着时间的推移而改变。
推荐阅读
- winapi - 在某些背景颜色上使用 DrawText() 绘制的文本(当 SetBkMode 为 TRANSPARENT 时)出现不可接受的斑点:如何克服?
- wordpress - 将第二个自定义菜单添加到全局上下文时出现问题
- javascript - 选项:在 javascript 中选择
- javascript - 在 Three.js 中将材质设置为网格的固定部分
- python - 导入错误_tkinter
- vba - vba 高效循环比较并复制和粘贴超过 10,000 个值
- mediawiki - 将 Mediawiki“wgUserName”传递给 Google 跟踪代码管理器
- c# - 使用 NEST / Elasticsearch.Net 执行原始 JSON 请求
- amazon-web-services - 将 s3 存储桶添加为 docker 卷
- pandas - 从 Pandas 数据框中提取数据作为列表,同时保留顺序