1

I'm having a hard time figuring out the solution to a problem that I thought would be very common or straight-forward to solve, but apparently I was wrong.

I have to re-write some web code (that I didn't write) that's causing a problem. When a user clicks a link, a request is sent to the web server, which in turn fetches or creates a PDF document from somewhere. The PDF data is returned with the Content-Disposition header set to attachment, and the browser shows the save-as dialog.

The reason the save-as dialog appears is because when the user clicks the link, the Javascript sets window.location.href to the server URL (with some parameters).

There's no loading animation other than the one the browser shows in the tab etc. while the request is being processed.

The problem is that if a request hangs or takes a while, users tend to click the link again (possibly multiple times) which means requests for that same resource just keep building up on the server (even accidental double clicks on a link, which are common, cause two requests to be processed).

How can I prevent this from happening? If I do something like this (with window.location.href replaced by window.open:

var REQUEST_PENDING = false;

function getPDF(param1, param2) {
    if (REQUEST_PENDING) return;
    REQUEST_PENDING = true;
    var w = window.open("/GetPdf.servlet?param1="+param1+"&param2="+param2);
    w.onload = function() {
        DOC_REQUEST_PENDING = false;
    }
}

...then only one request will be processed at any one time, but the onload callback only works if the return content is HTML. When it's an attachment, which is what I have, the DOC_REQUEST_PENDING variable is never set back to false, so no further requests can be made.

I know that the ultimate solution should probably be implemented server-side, but is it not possible to achieve what I'm trying to do client-side? (I can use jQuery).

RTF
  • 6,214
  • 12
  • 64
  • 132
  • One possibly oversimplified solution: change it to a button that gets disabled in the `getPDF` method. It would prevent double-clicks altogether, and you could change the text of the button to "Please wait..." or something. Unfortunately the headers that are used to force downloads are merely a mechanism used by the browser to do so and don't have anything to do with the DOM, really. – Cᴏʀʏ Oct 13 '14 at 13:44
  • You may also want to see this: http://stackoverflow.com/questions/1106377/detect-when-browser-receives-file-download. It would solve your problem but it's not a simple solution. – Cᴏʀʏ Oct 13 '14 at 13:46
  • @Cory But I would have thought the response indicating an attachment was irrelevant, I just need to detect that there was a response (any at all). Also, is changing to a button not the same situation. I still need to detect that the response has come in so I can re-enable the button? – RTF Oct 13 '14 at 13:47
  • That's why I said "oversimplified." You're right, you need to detect the response. The link I posted provides some trickery to do so. – Cᴏʀʏ Oct 13 '14 at 13:48
  • Yeah thanks - this question actually seems to be a duplicate of that one. – RTF Oct 13 '14 at 13:55

1 Answers1

1

The question linked to in the comments above by @Cory does seem to be a duplicate of my question, and while I'm sure the accepted answer is perfectly fine, there is a bit involved in it. There's another answer for that question down the list somewhat that provides a link to this jquery plugin:

http://johnculviner.com/jquery-file-download-plugin-for-ajax-like-feature-rich-file-downloads/

...and for me anyway, this is the ultimate solution. Easy to use and works great.

RTF
  • 6,214
  • 12
  • 64
  • 132