Skip to Content

How to Execute JavaScript After File Download is Completed in ASP.NET

  • The content is a blog article that explains how to execute JavaScript after file download is completed in ASP.NET.
  • The content discusses three possible solutions to the problem: using cookies, using AJAX, and using iframes. It also compares the pros and cons of each method and provides some code examples.

If you are working with ASP.NET web applications, you may encounter a situation where you need to execute some JavaScript code after a file download is completed. For example, you may want to show a loading animation while the file is being generated on the server side, and then hide it when the file is ready to be downloaded by the user. However, this is not as straightforward as it may seem, because the response object that is used to send the file to the browser also terminates the current page execution. Therefore, any JavaScript code that is registered after the file download will not be executed.

In this article, we will explore how to solve this problem using a few different approaches. We will also discuss the pros and cons of each method and provide some code examples.

How to Execute JavaScript After File Download is Completed in ASP.NET

The Problem

The user who posted the question had the following scenario:

  • They had a button on their web page that triggered a file download when clicked.
  • They used the OnClientClick attribute of the button to call a JavaScript function that showed a loading animation on the page.
  • They used the OnClick attribute of the button to call a server-side method that generated an Excel file and sent it to the browser using Response.Redirect.
  • They used ScriptManager.RegisterStartupScript to call another JavaScript function that hid the loading animation after the file download was completed.

However, they found out that the last JavaScript function was not executed and the loading animation remained visible on the page. They wanted to know how to fix this issue.

The Cause

The reason why the last JavaScript function was not executed was because of the way Response.Redirect works. According to the documentation, this method:

Ends execution of the current page and starts execution of a new page for the current request.

This means that when Response.Redirect is called, it sends an HTTP 302 status code to the browser, which instructs it to request a new URL. In this case, the new URL was pointing to another web form that handled the file download. However, this also means that any code that comes after Response.Redirect in the current page will not be executed, because the response object has already been flushed and closed. Therefore, the ScriptManager.RegisterStartupScript method had no effect and the JavaScript function that hid the loading animation was never called.

The Solutions

There are several possible solutions to this problem, each with its own advantages and disadvantages. We will discuss three of them in this article:

  • Using cookies
  • Using AJAX
  • Using iframes

Using Cookies

One possible solution is to use cookies to communicate between the current page and the download page. The idea is to set a cookie on the response object before sending the file to the browser, and then check for that cookie on the current page using JavaScript. When the cookie is detected, it means that the file download has started and we can hide the loading animation.

The steps for this solution are as follows:

  • On the server-side method that generates the file, add a cookie to the response object with a unique name and value. For example:
Response.Cookies.Add(new HttpCookie("FileDownload", "True"));
  • On the same method, redirect to another web form that handles the file download using Response.Redirect. For example:
Response.Redirect(String.Format("DownloadForm.aspx?FileName={0}&Path={1}", fileExported.Name, "Temp" + UserName));
  • On the download web form, get the file name and path from the query string parameters and send the file to the browser using Response.TransmitFile. For example:
string fileName = Request.QueryString["FileName"];
string path = Request.QueryString["Path"];
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
Response.TransmitFile(Server.MapPath(path + "/" + fileName));
Response.End();
  • On the current page, add a JavaScript function that checks for the cookie periodically using setInterval. When the cookie is found, clear the interval and hide the loading animation. For example:
var checkCookie = setInterval(function() {
  var cookie = document.cookie;
  if (cookie.indexOf("FileDownload=True") != -1) {
    clearInterval(checkCookie);
    LoadingLoopOff();
  }
}, 1000);
  • On the same page, add another JavaScript function that deletes the cookie after the file download is completed. This is to prevent the cookie from interfering with subsequent downloads. For example:
window.onload = function() {
  var cookie = document.cookie;
  if (cookie.indexOf("FileDownload=True") != -1) {
    document.cookie = "FileDownload=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
  }
};

The advantages of this solution are:

  • It is relatively simple and does not require much code changes.
  • It works across different browsers and devices.

The disadvantages of this solution are:

  • It relies on cookies, which may be disabled or blocked by the user or the browser settings.
  • It may not work well if multiple file downloads are initiated simultaneously or in a short time span, as the cookie may be overwritten or deleted before the download is completed.

Using AJAX

Another possible solution is to use AJAX (Asynchronous JavaScript and XML) to request the file from the server and then trigger the file download using JavaScript. The idea is to use an XMLHttpRequest object to send a GET request to the server and receive the file as a blob (binary large object). Then, use a URL.createObjectURL method to create a URL for the blob and assign it to an anchor element with a download attribute. Finally, use a click method to simulate a click on the anchor element and start the file download.

The steps for this solution are as follows:

  • On the server-side method that generates the file, do not use Response.Redirect, but instead return the file as a byte array using Response.BinaryWrite. For example:
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=" + fileExported.Name);
Response.BinaryWrite(fileBytes);
Response.End();
  • On the current page, add a JavaScript function that creates an XMLHttpRequest object and sends a GET request to the server with the file name and path as query string parameters. For example:
function downloadFile(fileName, path) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "DownloadForm.aspx?FileName=" + fileName + "&Path=" + path, true);
  xhr.responseType = "blob";
  xhr.onload = function() {
    if (this.status == 200) {
      var blob = this.response;
      var url = URL.createObjectURL(blob);
      var link = document.createElement("a");
      link.href = url;
      link.download = fileName;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
      LoadingLoopOff();
    }
  };
  xhr.send();
}
  • On the same page, modify the OnClientClick attribute of the button to call the downloadFile function instead of the showloadingGif_UPLOAD function. For example:
<input type="submit" name="ctl00$ContentPlaceHolder1$btnDownloadInfo" value="Report Download" onclick="downloadFile(fileExported.Name, 'Temp' + UserName);" id="ContentPlaceHolder1_btnDownloadInfo" class="btn btn-primary downnloadReport" />

The advantages of this solution are:

  • It does not rely on cookies or redirects, which may cause problems in some scenarios.
  • It allows more control over the file download process, such as showing progress indicators or handling errors.

The disadvantages of this solution are:

  • It requires more code changes and may not be compatible with older browsers that do not support XMLHttpRequest, URL.createObjectURL, or download attribute.
  • It may not work well with large files, as it may consume more memory and bandwidth.

Using iframes

A third possible solution is to use iframes (inline frames) to load the download web form in a hidden frame on the current page. The idea is to create an iframe element dynamically using JavaScript and set its source attribute to the download web form URL with the file name and path as query string parameters. Then, use an onload event handler to hide the loading animation when the iframe is loaded.

The steps for this solution are as follows:

  • On the server-side method that generates the file, redirect to another web form that handles the file download using Response.Redirect. This is similar to the first solution. For example:
Response.Redirect(String.Format("DownloadForm.aspx?FileName={0}&Path={1}", fileExported.Name, "Temp" + UserName));
  • On the download web form, get the file name and path from the query string parameters and send the file to the browser using Response.TransmitFile. This is also similar to the first solution. For example:
csharp string fileName = Request.QueryString[“FileName”]; string path = Request.QueryString[“Path”]; Response.ContentType = “application/vnd.openxmlformats-officedocument.spreadsheetml.sheet”; Response.AddHeader(“content-disposition”, “attachment;filename=” + fileName); Response.TransmitFile(Server.MapPath(path + “/” + fileName)); Response.End();
  • On the current page, add a JavaScript function that creates an iframe element and sets its source attribute to the download web form URL with the file name and path as query string parameters. For example:
javascript
function downloadFile(fileName, path) {
  var iframe = document.createElement("iframe");
  iframe.style.display = "none";
  iframe.src = "DownloadForm.aspx?FileName=" + fileName + "&Path=" + path;
  iframe.onload = function() {
    LoadingLoopOff();
  };
  document.body.appendChild(iframe);
}
  • On the same page, modify the OnClientClick attribute of the button to call the downloadFile function instead of the showloadingGif_UPLOAD function. For example:
<input type="submit" name="ctl00$ContentPlaceHolder1$btnDownloadInfo" value="Report Download" onclick="downloadFile(fileExported.Name, 'Temp' + UserName);" id="ContentPlaceHolder1_btnDownloadInfo" class="btn btn-primary downnloadReport" />

The advantages of this solution are:

  • It does not require much code changes and works across different browsers and devices.
  • It does not rely on cookies or AJAX, which may cause problems in some scenarios.

The disadvantages of this solution are:

  • It may not work well with large files, as it may consume more memory and bandwidth.
  • It may not be very secure, as the file download URL may be exposed in the iframe source attribute.

Conclusion

In this article, we have discussed how to execute JavaScript after file download is completed in ASP.NET. We have explored three possible solutions: using cookies, using AJAX, and using iframes. We have also compared the pros and cons of each method and provided some code examples. We hope that this article has been helpful and informative for you. If you have any questions or feedback, please feel free to leave a comment below.

Disclaimer: The article is not affiliated with, endorsed by, or sponsored by any other website. The article is for educational purposes only and does not constitute legal or technical advice. The article may contain errors, omissions, or inaccuracies. The user is responsible for verifying the accuracy and validity of the information before using it. The user is also responsible for complying with any applicable laws and regulations when using the information.