我正在从第三方API下载动态生成的PDF,并将其显示给最终用户。使用URL.createObjectURL()
可以很好地工作,唯一的例外是在新窗口中显示文件(或窗口)时,我无法设置文件的标题。 2013年的This问题本质上是相同的问题,但没有针对此特定问题的解决方案。在将对象URL分配为新位置之前和之后,我都尝试过编辑newWindow.document.title
。我的猜测是这根本不可能,但我还是想问一下。
注意:我无法控制PDF或生成它的API。我也没有选择在此应用程序和API之间插入本地服务器,这是我的首选解决方案(因此我可以调用API并设置Content-Disposition
标头)。我正在使用一个看起来像location
的URL来设置新窗口的blob:http://localhost:3000/1e1e526d-ff4d-4797-9e5d-b4327813a747
。保存此文件将产生一个对话框,其中包含诸如1e1e526d-ff4d-4797-9e5d-b4327813a747
之类的预填充文件名。问题是是否可以更改该文件名。
以下是用于提取文件并将其显示在新窗口中的代码,以供参考(这是一个Angular应用程序):
let isMSIEorEdge = window.navigator && window.navigator.msSaveOrOpenBlob;
// Create the URL
let url = <API_URL>;
// Create the JSON data to send
let data = {
... API-specific data ...
};
// Set up basic headers
let headers = new Headers();
headers.append('Content-Type', 'application/json');
// For non-MS browsers, open a new window to show the document in
// This must be done here because it's still part of the user-initiated
// action (mouse click)
let newWin;
if (!isMSIEorEdge) {
newWin = window.open('', 'pdfWindow');
}
// Call the method and subscribe to the result
this.http
.post(url, data, {
headers,
responseType: ResponseContentType.Blob
})
.subscribe(
res => {
// Get the filename from the response headers
let filename = res.headers
.get('content-disposition')
.match(/filename=(.*)$/)[1];
// Create a File object from the data
let file = new File([res.blob()], filename, {
type: 'application/pdf'
});
// For IE/Edge, trigger Save/Open dialog
if (isMSIEorEdge) {
window.navigator.msSaveOrOpenBlob(file, filename);
return false;
}
// For all other browsers, open in new window
let href = window.URL.createObjectURL(file);
newWin.location.assign(href);
newWin.name = newWin.document.title = filename;
// Clear the object URL to avoid memory leaks
setTimeout(() => {
window.URL.revokeObjectURL(href);
}, 100);
},
err => {
// Handle any HTTP errors
console.log(err);
throw err;
}
);
}