Friday, September 8, 2017

jQuery Detect when browser receives file download | Detecting the File Download Dialog In the Browser

Client Side:

<script src="./../jquery-2.1.4.js"></script>

<script type="text/javascript">
$(document).ready(function () {

var downloadToken = new Date().getTime();

$("button").click(function () {
    downloadToken = new Date().getTime();
    $("[name='downloadToken']").val(downloadToken);
    $("form").trigger("submit");
    timer();
});

function timer() {
    var attempts = 100; /* As you required */
    var downloadTimer = window.setInterval(function () {
        var token = getCookie("downloadToken");
        attempts--;

        if (token == downloadToken || attempts == 0) {
            $(".log").prepend("Browser received file from server<br/>");
            window.clearInterval(downloadTimer);
        }
        else {
            $(".log").prepend("Browser not received file from server yet<br/>");
        }
    }, 1000);
}

function parse(str) {
    var obj = {};
    var pairs = str.split(/ *; */);
    var pair;
    if ('' == pairs[0]) return obj;
    for (var i = 0; i < pairs.length; ++i) {
        pair = pairs[i].split('=');
        obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }
    return obj;
}

function getCookie(name) {
    var parts = parse(document.cookie);
    return parts[name] === undefined ? null : parts[name];
}

});
</script>

<form action="download.php" method="post">
    <input type="hidden" name="downloadToken"/>
    <button type="button">Download</button>
    <div class="log"></div>
</form>

Server Side Script as of PHP:

<?php
$file_name = "download.zip";
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=download.zip');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_name));

// Sleep 5 seconds...
sleep(5);

// Cookie will be expire after 20 seconds...
setcookie("downloadToken", $_POST["downloadToken"], time() + 20, "");

ob_clean();
flush();
readfile($file_name);

Browser Screenshot:






4 comments:

  1. Nice article.. thanks

    ReplyDelete
  2. Why is it necessary to clean and flush the output buffer before reading file?
    I removed them and it works just fine.
    Please anybody?

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. You usually do this sort of thing to guarantee that the file you are sending starts at the beginning of the buffer before you send it to the client.

      Delete