0

I want to download a file from my web server to my internet page without a real-human clicking or page-load event. It seems rather easy to put these event handlers into the HTML, but I haven't been able to find a solution where jQuery or JavaScript can download a file with a line or two of code, not using a human event.

For more background, I am using AJAX. The user clicks a button, which sets off the AJAX request, which calls a PHP file, which does some work and creates a log file. It can take up to 10 minutes to make the log file so that it is ready to be downloaded. If the AJAX request returns with certain conditions, I want the file to be downloaded to the browser, and if not, then I want it to download nothing. I want it so that the user can kick off the process, go bake a cake, come back, and see that the file has been downloaded.

$.ajax({
  type: "POST",
  url: "/php/do_work.php",
  data:{'foo':bar},
  dataType: 'text',
  success : function(listen_up) {
    if (listen_up == "hide yo kids") {
      //download file to browser
    } else if (listen_up == "hide yo wife") {
      //do something else
    }
//the rest of the ajax request...

I want the download to indicate success by putting the filename at the bottom left of the browser window, as seen in the following image:

enter image description here

I am also okay with HTML solutions, as long as they can somehow wait until the AJAX request is done before initiating the download. I am also fine with events, as long as the human-user doesn't have to be the one that sets it off. I would also rather not have to use more server resources than necessary, such as polling, as I would like the server's full attention on creating the log files... but that would an adequate answer if there was no other way.

JCollier
  • 1,102
  • 2
  • 19
  • 31
  • 4
    That's just not how all this works. First of all no browser (none, nada) is going to wait 10 minutes for an Ajax call to return. So unless you want to continually make Ajax requests to the server to see if the file is done, you're going to need user interaction and that is called an event. – gforce301 Apr 13 '18 at 20:30
  • Why would a user want this? – JGallardo Apr 13 '18 at 20:31
  • Because the user clicks a button, and then there is some pretty intense processing that happens, so the file will be downloaded as soon as it is ready. I want it to download without them having any further interaction. I've seen it done before, so I know it can be done. Also, I know for a fact the AJAX call returns after over 10 minutes, because I've put an `alert()` in the success portion of the call, and it still alerts after that duration. – JCollier Apr 13 '18 at 20:33
  • 1
    For security reasons, downloads to a PC can only be performed with a click. You can do AJax requests and store the result client side, but the actual final part of the user been able to download needs to be actioned by the user. – Keith Apr 13 '18 at 20:37
  • @Keith Wrong. _"Your download will start shortly..."_ ➡ https://sourceforge.net/projects/scribus/files/latest/download – blex Apr 13 '18 at 20:39
  • Well, if it isn't possible, then that would be an adequate answer to this question. This is something that would legitimately be helpful for my web page, so I don't think this is a dumb question based on my current understanding of web development. I've also seen it done before. – JCollier Apr 13 '18 at 20:41
  • 1
    Possible duplicate of [Is it possible to trigger file download to a user's browser?](https://stackoverflow.com/questions/11867096/is-it-possible-to-trigger-file-download-to-a-users-browser) – Herohtar Apr 13 '18 at 20:42
  • @blex Yes, sorry. I'm mixing up with uploads. The user still needs to action the download after, so the security aspects are still valid. – Keith Apr 13 '18 at 20:44
  • @Herohtar I didn't read it carefully enough. I stand corrected. – gforce301 Apr 13 '18 at 20:46

2 Answers2

1

Another simple solution would be as soon as the ajax response comes back. Create anchor tag link with href attribute and download attribute pointing to where you stored the file using javascript and trigger click event on it.

So that's the code snippet you should use in the ajax success function:

if (response.condition_is_met) {
    var a = document.createElement ('a');
    a.setAttribute ('href', response.log_file_path);
    a.setAttribute ('download');
    a.click ();
}

And as mentioned above you would probably need to use long polling because on chrome for example the allowed max timeout for ajax calls is 1min.

Later it would be also needed to run a cronjob to delete the old created logs to keep your server clean.

Eden Reich
  • 387
  • 2
  • 7
0

Ok so you will need a long polling loop. Take a look at this: What is the proper way of doing long polling using jQuery and AJAX You'll have to ask the server repeatedly over time if the file is done and ready for download.

Your initial Ajax call needs to return right away and let go. The response for it is basically just telling the browser "Ok I got the request to make the file".

When your server has the file ready for download it will notify the browser on whatever path you are polling. Then you can trigger some javascript to go get the file and download it.

The other option instead of long polling would be websockets. That's another animal all together but in essence it's the same flow. Browser makes Ajax request to start file creation OR sends a websocket message to do the same. Once file is ready server sends a socket message telling the browser to initiate download.

gforce301
  • 2,944
  • 1
  • 19
  • 24