I'm having a situation in which I want to allow the user to download a PDF. The generation of this PDF can take a couple of seconds, and I don't want a webserver thread to wait for the generation of the PDF, since that means the thread isn't available to handle other incoming requests.
So, what I would like to do is introduce the following URL patterns:
/request_download
which invokes a background job to generate the PDF;/document.pdf
which will serve the PDF once it is generated
The use case is as follows.
A user clicks on 'Download PDF'. This invokes a piece of Javascript that'll show a spinner, make a request to /request_download
and receive a HTTP 202 Accepted, indicating the request was accepted and a background job was created. The JS should then poll the /request_download
url periodically until it gets HTTP 201 Created, indicating that the PDF has been created. A Location
header is included that is used by the JS to forward the client to /document.pdf
. This has to be in a new window (or tab, at least it shouldn't replace the current page). The level of expertise of our users is very low, so when I forward to the url, they might not know how to get back to the website.
The problem
Now, window.open
works fine if it is invoked by the user via a click event. However, I want to invoke window.open
in a callback function through setInterval
as soon as I see that 201 Created response. However, browsers won't like that and will interpret it as a popup, causing it to get caught by popup blockers on IE8-10 as well as Chrome. Which makes sense.
I also can't open a new window and invoke the Javascript over there. In that case, users would see a blank page with a spinner. If that page then forwards to the /document.pdf
, IE will show this yellow warning bar telling that it prevented files from being downloaded. Chrome and Firefox will do this without any problems, but a large percentage of our users is on IE.
What I've tried, and didn't work
- window.open(location)
- Setting the src of an iframe to the retrieve location
- Manually adding an
<a>
tag to the document body and trying to click it using javascript - Adding an
<a>
tag to the document body and invoking aMouseEvent
on it - Partially works: opening a new window on user click and storing a reference to it, then perform the asynchronous requests and upon completion, set the location of the earlier opened window. But: IE will block this and say it prevented files from being downloaded. So still not a fully working solution.
I'm straight out of ideas on how I can make this work and decided and decided to ask The Internet for help. I'm hoping you guys can help me with this, or recognise the problem. Thanks in advance!