Handle file download from ajax post

前端 未结 20 2637
心在旅途
心在旅途 2020-11-21 05:46

I have a javascript app that sends ajax POST requests to a certain URL. Response might be a JSON string or it might be a file (as an attachment). I can easily detect Content

20条回答
  •  心在旅途
    2020-11-21 06:08

    I see you've already found out a solution, however I just wanted to add some information which may help someone trying to achieve the same thing with big POST requests.

    I had the same issue a couple of weeks ago, indeed it isn't possible to achieve a "clean" download through AJAX, the Filament Group created a jQuery plugin which works exactly how you've already found out, it is called jQuery File Download however there is a downside to this technique.

    If you're sending big requests through AJAX (say files +1MB) it will negatively impact responsiveness. In slow Internet connections you'll have to wait a lot until the request is sent and also wait for the file to download. It isn't like an instant "click" => "popup" => "download start". It's more like "click" => "wait until data is sent" => "wait for response" => "download start" which makes it appear the file double its size because you'll have to wait for the request to be sent through AJAX and get it back as a downloadable file.

    If you're working with small file sizes <1MB you won't notice this. But as I discovered in my own app, for bigger file sizes it is almost unbearable.

    My app allow users to export images dynamically generated, these images are sent through POST requests in base64 format to the server (it is the only possible way), then processed and sent back to users in form of .png, .jpg files, base64 strings for images +1MB are huge, this force users to wait more than necessary for the file to start downloading. In slow Internet connections it can be really annoying.

    My solution for this was to temporary write the file to the server, once it is ready, dynamically generate a link to the file in form of a button which changes between "Please wait..." and "Download" states and at the same time, print the base64 image in a preview popup window so users can "right-click" and save it. This makes all the waiting time more bearable for users, and also speed things up.

    Update Sep 30, 2014:

    Months have passed since I posted this, finally I've found a better approach to speed things up when working with big base64 strings. I now store base64 strings into the database (using longtext or longblog fields), then I pass its record ID through the jQuery File Download, finally on the download script file I query the database using this ID to pull the base64 string and pass it through the download function.

    Download Script Example:

    MyQueries->GetDownload( $downloadID );
    // base64 tags are replaced by [removed], so we strip them out
    $base64     = base64_decode( preg_replace('#\[removed\]#', '', $data[0]->image) );
    // This example is for base64 images
    $imgsize    = getimagesize( $base64 );
    // Set content headers
    header('Content-Disposition: attachment; filename="my-file.png"');
    header('Content-type: '.$imgsize['mime']);
    // Force download
    echo $base64;
    ?>
    

    I know this is way beyond what the OP asked, however I felt it would be good to update my answer with my findings. When I was searching for solutions to my problem, I read lots of "Download from AJAX POST data" threads which didn't give me the answer I was looking for, I hope this information helps someone looking to achieve something like this.

提交回复
热议问题