5

I am trying to download PDF file from FTP server with Jquery Ajax request. I referred http://www.dave-bond.com/blog/2010/01/JQuery-ajax-progress-HMTL5/.

My Jquery ajax call is as below

 $.ajax({
                 xhr: function () {
                     var xhr = new window.XMLHttpRequest();
                   
                     //Download progress
                     xhr.addEventListener("progress", function (evt) {
                         console.log("Event :"+evt.lengthComputable);
                         if (evt.lengthComputable) {
                             var percentComplete = evt.loaded / evt.total;
                             //Do something with download progress
                             console.log(percentComplete);
                         }
                     }, false);
                     return xhr;
                 },
                 type: 'POST',
                 url: "Downloader.ashx",
             
                 success: function (data) {
                     //Do something success-ish
                 }
             });

And My C# generic handler code to download file is as below

  public void ProcessRequest(HttpContext context)
        {
            DownLoadFilesFromFTp("MyFile.pdf", "Foldername");
            
        }
        public bool DownLoadFilesFromFTp(string fileName,string ftpFolder)
        {
            //Create FTP Request.
            try
            {
                string Ftp_Host = System.Configuration.ConfigurationManager.AppSettings["Ftp_Host"];
                string Ftp_UserName = System.Configuration.ConfigurationManager.AppSettings["Ftp_UserName"];
                string Password = System.Configuration.ConfigurationManager.AppSettings["Password"];
                string downloadpath= System.Configuration.ConfigurationManager.AppSettings["downloadpath"];
                //Fetch the Response and read it into a MemoryStream object.
                string ftpurl = Ftp_Host + ftpFolder + "/" + fileName;
                FtpWebRequest reqFTP;
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpurl));
                reqFTP.Credentials = new NetworkCredential(Ftp_UserName, Password);
                reqFTP.KeepAlive = false;
                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                reqFTP.UseBinary = true;
                reqFTP.Proxy = null;
                reqFTP.UsePassive = false;

                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                Stream responseStream = response.GetResponseStream();
                FileStream writeStream = null;
                //if (fileName.Substring(fileName.Length - 3, 3) == "pdf" || fileName.Substring(fileName.Length - 3, 3) == "PDF")
                //{
                writeStream = new FileStream(downloadpath + fileName, FileMode.Create);


                //}
                int Length = 2048;  // 2048;

                Byte[] buffer = new Byte[Length];
                int bytesRead = responseStream.Read(buffer, 0, Length);
                while (bytesRead > 0)
                {
                    writeStream.Write(buffer, 0, bytesRead);
                    bytesRead = responseStream.Read(buffer, 0, Length);
                }


                responseStream.Close();
                writeStream.Close();
                response.Close();
                return true;
            }
            catch (WebException wEx)
            {
                return false;

            }
            catch (Exception ex)
            {
                return false;

            }
        }

When I run a code files downloads to a folder without any issues and on Ajax call
if (evt.lengthComputable) {
}

When I console evt i got below result
enter image description here Always returns false so i am unable to track a progress.

1) is there anything wrong with the code ?
2) Any alternative way to show progress bar while downloading pdf

Ali Soltani
  • 9,589
  • 5
  • 30
  • 55
Narasappa
  • 546
  • 1
  • 9
  • 31
  • Please see this answer: https://stackoverflow.com/questions/16034312/ajax-xhr-lengthcomputable-return-false-with-php-file Your downloader needs to output `Content-length` header. Logically, how can you know the percent downloaded if you do not know the total file size? – dkasipovic Feb 14 '18 at 13:40
  • The generic handler C# code downloads the file to the local directory without any issues. only thing is to show a Progress bar while downloading. – Narasappa Feb 15 '18 at 05:30
  • You should serve the file with a content-length. Look at this https://stackoverflow.com/questions/26362419/how-to-stream-file-from-disk-to-client-browser-in-net-mvc and adapt your code – Tarun Lalwani Feb 15 '18 at 09:52
  • have you searched the internet or come across this link ? https://stackoverflow.com/questions/12519290/downloading-files-using-ftpwebrequest – CME64 Feb 19 '18 at 13:28

2 Answers2

3

For the bytes uploaded, it is quite easy to show progress bar. Just monitor the xhr.upload.onprogress event. The browser knows the size of the files it has to upload and the size of the uploaded data, so it can provide the progress info.

For the bytes downloaded, it is a little bit more difficult, because the only thing that the browser knows in this case is the size of the bytes it is receiving.

The reason of evt.lengthComputable is 0 is that the browser doesn't know how many bytes will be sent in the server request.

There is a solution for this, it's sufficient to set a Content-Length header on the server like below, in order to get the total size of the bytes the browser is going to receive.

// prepare the response to the client. resp is the client Response
var resp = HttpContext.Current.Response;
// Add Content-Length of the file to headers
// if the headers is not set then the evt.loaded will be 0
resp.AddHeader("Content-Length", "lengthOfYourFile");
Ali Soltani
  • 9,589
  • 5
  • 30
  • 55
2

Your code JS side look fine. I am not C# programmer, but i observed that C# server side, download the file ftp and save it to disk server, but never response/send the PDF binary to JS SIDE? From JS side is 0 bytes download. and evt.lengthComputable is alway false/0.

toto
  • 1,180
  • 2
  • 13
  • 30