[Melbourne-pm] Forcing a download

Toby Wintermute tjc at wintrmute.net
Mon Jan 20 16:50:06 PST 2014


On 21 January 2014 11:15, Gary Smith <gary at devgurus.com> wrote:
> Hi All,
>
> As this is my first post to the list I'll do a quick bio. I've been using
> Perl since v3 - that was for my ISP business where I wrote our in-house
> accounting system for dialup clients in Perl back in the late 90's. Since
> then I'va also used it to do the heavy lifting on a hit counter, sorting
> 6-8mil hits per day into a cluster of MySQL servers and various other
> smaller jobs.
>
> Fast forward to today and I'm working on a project that is
> Catalyst/Postgresql/Starman based and I've struck a problem that is quite
> irritating as it's a simple task that looks right but doesn't act as it
> should. I'm creating a file and then I want it to pop up a dialog to
> download that file. The request is posted via jquery/ajax, the file is
> generated and it then sends it back to the browser with some appropriate
> headers. Here's the code:

Hi Gary,
I noticed some issues in your code; I don't know if any of them are
actually causing the issue you're facing, but it can't hurt to fix
them just in case.

1) If _do_my_export() fails inside the try/catch block, you'll log the
errors but then continue executing the rest of the code that relies
upon $result being set. (except it won't be what you expect -- it'll
be set to the return value from $c->response->body)

2) In some error cases, you'll never clean up your temporary files.
Try using File::Temp->new, which will automatically clean up the file
once the reference goes out of scope.

3) Put the second half of your routine into the try/catch block as
well, and die out of it if you fail to open the file, or the file is
zero bytes, rather than fall through to that empty TODO block. That
way you can get free error handling for it -- and it may well explain
why your code isn't working properly if that's where the error is.

However.. I don't think browsers like accepting file downloads via
ajax requests like that.
Can you try this instead: Make the ajax post query as you are now, but
instead of returning the file data, return a URL that, when accessed,
returns the file data. Then on the webpage, redirect the page to that
URL.
ie. in your $.post() method, the success handler would be something like
function(data) {
  if (data.success) { window.document.href = data.url;}
  else { show_message_to_user(data.error_message); }
}

Cheers,
Toby


More information about the Melbourne-pm mailing list