how to caputre the file downloading event and stop the spining icon.

I am trying to capture the event of the file downloading such that the spinning loader can be stopped, however, I tried multiple ways, it's still not working yet. please see my code below:

<script type="text/javascript">
$(document).ready(function(){
    $(":submit").click(function() {   	
        $('#loader').show();
    
/*
* above block of code works, below block does not
*    
        var fileDownloadCheckTimer;
        fileDownloadCheckTimer = window.setInterval(function(){
        var cookieValue = getCookie('fileDownloadToken');
        if(cookieValue == "fileIsReady") {
        	$('#loader').hide();
        	finishDownload();}
        },1000);
        
    });
});



/**
 * Get a cookie
 * @param {String} cname, cookie name
 * @return {String} String, cookie value 
 */
function getCookie(cname) {
    var name = cname + "="; //Create the cookie name variable with cookie name concatenate with = sign
    var cArr = window.document.cookie.split(';'); //Create cookie array by split the cookie by ';'
     
    //Loop through the cookies and return the cooki value if it find the cookie name
    for(var i=0; i<cArr.length; i++) {
        var c = cArr[i].trim();
        //If the name is the cookie string at position 0, we found the cookie and return the cookie value
        if (c.indexOf(name) == 0) {
        	document.getElementById("demo").innerHTML = c.substring(name.length, c.length);;
            return c.substring(name.length, c.length);
        }
    }
     
    //If we get to this point, that means the cookie wasn't find in the look, we return an empty string.
    return "";
}
 
 /**
  * Delete a cookie
  * @param {String} cname, cookie name
  */
 function deleteCookie(cname) {
     var d = new Date(); //Create an date object
     d.setTime(d.getTime() - (1000*60*60*24)); //Set the time to the past. 1000 milliseonds = 1 second
     var expires = "expires=" + d.toGMTString(); //Compose the expirartion date
     window.document.cookie = cname+"="+"; "+expires;//Set the cookie with name and the expiration date
  
 }

function finishDownload(){
	
	window.clearInterval(fileDownloadCheckTimer);
	deleteCookie('fileDownloadToken');
    hideConfirm();		
}

function hideConfirm() {
    var x = document.getElementById("loader");
    if (x.style.display == "block") {
        x.style.display = "none";
    } 
}

</script>

Open in new window


the servlet send out the cookie "fileIsReady" for the browser to capture:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		.........
		
		response.setContentType("application/octet");

		response.setHeader("Content-disposition", "attachment;filename=" + filename);

		Cookie cookie = new Cookie("fileDownloadToken", "fileIsReady");
		
		log.info("file download cookie is: " + cookie);
		response.addCookie(cookie);//for download signals
		
		ServletOutputStream sos = response.getOutputStream();
		workbook.write(sos);
		sos.flush();
		sos.close();
		workbook = null;
		log.debug("Finished to output excel stream.");

		
	}

Open in new window


My loader just keep running even though the file downloading has completed, which means the cookie---fileIsReady never been captured,  I carefully checked my source, nothing wrong, and the server does not report any error messages. can anybody help?
Arthur WangAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

leakim971PluritechnicianCommented:
open a browser like chrome, do a right click on your page and click on Inspect
On the "Network" tab, check the different traffic, locate your file downloading, click on it, check the header, especially the response and check if you see you cookie
else post more of your code, a basic HTML part and the servlet java code
Arthur WangAuthor Commented:
more detailed code blow:

html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<title><bean:message key="system.name"/></title>

<!-- The block below is for bootstrap integration -->        
  	    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">	
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">        
        <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css" >	 
		<script type="text/javascript" src="/kiosk_resources/javascript/jquery-2.1.4.min.js"></script>	
		<script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>	
<!-- above block is for bootstrap integration -->  

<script language="JavaScript" src="/kiosk_resources/javascript/calendar2.js"></script> 
<script type="text/javascript" language="JavaScript1.2" src="/kiosk_resources/javascript/date.js"></script>
<!-- above block is for calendar and date display -->


        <link rel="stylesheet" href="/kiosk_resources/javascript/jquery-ui.css">
        <script src="/kiosk_resources/javascript/jquery-ui.js"></script>  
  <script>
  $( function() {
    $( "#datepicker1, #datepicker2" ).datepicker();
  } );
  </script>

 
<style>
 select {
  height: 30px;
  padding: 5px 10px;
  cursor:pointer;
}
</style>  
 
<style>
.loader {
  border: 16px solid #f3f3f3;
  border-radius: 50%;
  border-top: 16px solid #3498db;
  width: 120px;
  height: 120px;
  -webkit-animation: spin 2s linear infinite; /* Safari */
  animation: spin 2s linear infinite;
    position:fixed;
    top: 60%;
    left: 60%;
    margin-top: -15em; /*set to a negative number 1/2 of your height*/
    margin-left: -15em; /*set to a negative number 1/2 of your width*/
    z-index: 1000;
}


/* Safari */
@-webkit-keyframes spin {
  0% { -webkit-transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
</style>

<script type="text/javascript">
$(document).ready(function(){
    $(":submit").click(function() {   	
        $('#loader').show();
        
        var fileDownloadCheckTimer;
        fileDownloadCheckTimer = window.setInterval(function(){
        var cookieValue = getCookie('fileDownloadToken');
        if(cookieValue == "fileIsReady") {
        	$('#loader').hide();
        	finishDownload();}
        },1000);
        
    });
});



/**
 * Get a cookie
 * @param {String} cname, cookie name
 * @return {String} String, cookie value 
 */
function getCookie(cname) {
    var name = cname + "="; //Create the cookie name variable with cookie name concatenate with = sign
    var cArr = window.document.cookie.split(';'); //Create cookie array by split the cookie by ';'
     
    //Loop through the cookies and return the cooki value if it find the cookie name
    for(var i=0; i<cArr.length; i++) {
        var c = cArr[i].trim();
        console.log(c);
        //If the name is the cookie string at position 0, we found the cookie and return the cookie value
        if (c.indexOf(name) == 0) {
        	document.getElementById("demo").innerHTML = c.substring(name.length, c.length);
        	console.log(c.substring(name.length, c.length));
            return c.substring(name.length, c.length);
        }
    }
     
    //If we get to this point, that means the cookie wasn't find in the look, we return an empty string.
    return "";
}
 
 /**
  * Delete a cookie
  * @param {String} cname, cookie name
  */
 function deleteCookie(cname) {
     var d = new Date(); //Create an date object
     d.setTime(d.getTime() - (1000*60*60*24)); //Set the time to the past. 1000 milliseonds = 1 second
     var expires = "expires=" + d.toGMTString(); //Compose the expirartion date
     window.document.cookie = cname+"="+"; "+expires;//Set the cookie with name and the expiration date
  
 }

function finishDownload(){
	
	window.clearInterval(fileDownloadCheckTimer);
	deleteCookie('fileDownloadToken');
    hideConfirm();		
}

function hideConfirm() {
    var x = document.getElementById("loader");
    if (x.style.display == "block") {
        x.style.display = "none";
    } 
}

</script>



</head>
<!-- above block is for jquery datepicker reference -->  

<body>


	<div class="container">
 	<div class="wrapper"> 
 	<div class="col-xs-12 col-md-10 col-md-offset-1 col-lg-10 col-lg-offset-1">






<form action="/.................../queryVisitReportByCustId.do" >

 <div class="form-group row"> 
		
	          <div class="col-xs-9" >
		
		        <br>
		        
				<div class="col-xs-6" >
				 <div class="input-group">
                  <span class="input-group-addon">
				     
				  </span>  
				  <input id="datepicker1" class="form-control" type="text" name="beginDate" placeholder="Begin Date example: 01/01/2018" value="">	
				  		
				</div>
				</div>
			

				<div class="col-xs-6" >
				 <div class="input-group">
                  <span class="input-group-addon">
				
				</span> 
				<input id="datepicker2" class="form-control" type="text" name="endDate" placeholder="End Date example: 01/01/2019" value="">				 
				</div>
				</div>
				
				<br>
				<br>
				<br>

				<button type = "submit" class ="btn btn-primary">Download Visit History</button>
         
              </div>
              
             </div>

 			
	</form>	
		
		
	</div>   
	</div>
	</div>	

   		
<!-- END CONTENT-->

</body>
</html>

Open in new window


servlet:

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.log4j.*;


public class OutputExcelServlet extends HttpServlet
{
	private static final long serialVersionUID = 6141531853383840414L;

	private final static Logger log = LogManager.getLogger(OutputExcelServlet.class);

	public OutputExcelServlet()
	{
		super();
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{

		log.debug("== excel filename:" + filename + ",workbook:" + workbook + ",beginDate:" + beginDate + ",endDate:" + endDate);

		response.setContentType("application/octet");

		response.setHeader("Content-disposition", "attachment;filename=" + filename);

		Cookie cookie = new Cookie("fileDownloadToken", "fileIsReady");
		
		log.info("file download cookie is: " + cookie);
		response.addCookie(cookie);   //for download signals
		
		ServletOutputStream sos = response.getOutputStream();
		workbook.write(sos);
		sos.flush();
		sos.close();
		workbook = null;
		log.debug("Finished to output excel stream.");

	
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		doGet(request, response);
	}

	public void init() throws ServletException
	{
	}
}

Open in new window

leakim971PluritechnicianCommented:
so did you check the header with the browser?
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

Arthur WangAuthor Commented:
For some reason, this is a production site, and the previous engineer disabled the right click, and embedded the web page into an iframe for extra security. I probably have to setup a testing site, but that takes time to do it.
leakim971PluritechnicianCommented:
Mac or Windows ?
Arthur WangAuthor Commented:
thanks, but none of them works for me because the page is embedded inside another iframe. by the way, I use mac.
leakim971PluritechnicianCommented:
iframe is not an issue, you see all traffics...
Arthur WangAuthor Commented:
I am able to see the response header from inspector--> network:

Response headers (284 B)	
Connection	
Keep-Alive
Content-disposition	
attachment;filename=VisitHistoryByCustomerID.xls
Content-Type	
application/octet
Date	
Fri, 19 Oct 2018 05:14:24 GMT
Keep-Alive	
timeout=5, max=100
Server	
Apache/2.4.6 () mod_jk/1.2.43
Transfer-Encoding	
chunked

Open in new window


the console:

An unbalanced tree was written using document.write() causing data from the network to be reparsed. For more information https://developer.mozilla.org/en/Optimizing_Your_Pages_for_Speculative_Parsing

Open in new window


Screen-Shot-2018-10-18-at-10.28.53-P.pngI don't see the cookie which I sent from the servlet in the response header:

Cookie cookie = new Cookie("fileDownloadToken", "fileIsReady");
		
		log.info("file download cookie is: " + cookie);
		response.addCookie(cookie);//for download signals

Open in new window

though I am able to see it from the server log.
that's weird.
Arthur WangAuthor Commented:
Since there is no way for me to capture the cookie at the browser, I am looking at the alternative solution, maybe try to capture the file name?

<script type="text/javascript">
$(document).ready(function(){
    $(":submit").click(function() {   	
        $('#loader').show();
        
        
        var request = new XMLHttpRequest();
        
        request.onload = function() {
          // Only handle status code 200
          if(request.status === 200) {
            // Try to find out the filename from the content disposition `filename` value
            var disposition = request.getResponseHeader('content-disposition');
            var matches = /"([^"]*)"/.exec(disposition);
            var filename = (matches != null && matches[1] ? matches[1] : 'VisitHistoryByCustomerID.xls');

            $('#loader').hide();
            hideConfirm();	
            }//if status 200
        };//onload function
    });//click function
});//ready function

function hideConfirm() {
    var x = document.getElementById("loader");
    if (x.style.display == "block") {
        x.style.display = "none";
    } 
}

Open in new window

the html code is:
<div id="loader" class="loader" style="display:none;"></div>  

Open in new window

however, the browser can not capture the event based on my testing, is my javascript code for the comparision correct?
leakim971PluritechnicianCommented:
just did a simple test to  download a file and the cookie is well present

cookie present
package gp.leakim;

import java.io.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "DownloadServlet")
public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;


    private static String strfilepath = "/Users/leakim/Desktop/test.txt";

    public DownloadServlet() {
        super();
    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie cookie = new Cookie("fileDownloadToken", "fileIsReady");
        response.addCookie(cookie);
        File fFile = new File(strfilepath);
        BufferedInputStream in = null;
        BufferedOutputStream sosStream = null ;
        try
        {
            response.setContentType( "application/octet-stream" );
            response.setHeader( "Content-Disposition", "attachment; filename=test.txt");
            in = new BufferedInputStream( new FileInputStream( fFile ) ) ;
            sosStream = new BufferedOutputStream( response.getOutputStream() ) ;

            byte[] buf = new byte[ 4 * 1024 ];  // 4K buffer
            int bytesRead;
            while( ( bytesRead = in.read( buf ) ) != -1 )
            {
                sosStream.write( buf, 0, bytesRead ) ;
            }
            sosStream.flush();
        }
        catch( IOException ex )
        {
            ex.printStackTrace() ;
        }
        finally
        {
            try { if( in != null) in.close(); } catch( IOException ex ) { }
            try { if( sosStream != null) sosStream.close(); } catch( IOException ex ) { }
        }
    }

}

Open in new window


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <form action="DownloadIt">
    <button type="submit">SUBMIT</button>
  </form>
  </body>
</html>

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Arthur WangAuthor Commented:
that's amazing, thanks for the testing code, which prove the cookies can be sent to the browser, however, for some reason my browser just can not see it, is it because I use struts ?
leakim971PluritechnicianCommented:
what you post does'nt look like struts...
Arthur WangAuthor Commented:
Leakim971, maybe we can setup a time such that I could hire you as an expert to help me solve the problem? I am at the PST time zone.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.