2

I'm downloading a dynamically generated PDF from a 3rd party API and displaying it to the end user. This works great, using URL.createObjectURL(), with the sole exception that I can't set the title of the file (or window) when presenting it in a new window. This question from 2013 has essentially the same problem, but no solutions to this particular issue. I've tried editing newWindow.document.title both before and after assigning the object URL as the new location with no luck. My guess is that this is simply impossible, but I thought I'd ask anyway.

Note: I have no control over the PDF or the API generating it. I also don't have the option of inserting a local server between this app and the API, which would be my preferred solution (so I could call the API and set the Content-Disposition headers). I'm setting the location of a new window with a URL that looks like blob:http://localhost:3000/1e1e526d-ff4d-4797-9e5d-b4327813a747. Saving this file yields a dialog box with a pre-filled filename like 1e1e526d-ff4d-4797-9e5d-b4327813a747. The question is whether it's possible to change that filename.

Here's the code used to fetch the file and display it in a new window, for reference (this is an Angular app):

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;
    }
  );
}
ken.dunnington
  • 905
  • 1
  • 7
  • 20
  • 1
    This question is substantially different from the proposed duplicate. The proposed duplicate asks how to change the file name in the pdf source while this question asks how to change the file name as part of the client JavaScript. – Richard Collette Mar 23 '20 at 21:08
  • This is a completely different question, I would request to reopen this question. – shaswat.dharaiya Jun 18 '21 at 13:28

0 Answers0