设置在新窗口中打开的Blob URL的文件名/标题

时间:2019-05-29 19:41:34

标签: javascript

我正在从第三方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;
    }
  );
}

0 个答案:

没有答案