Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Download PDF file With FTP using XMLHttpRequest and generic handler

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

like image 351
Narasappa Avatar asked Nov 22 '17 07:11

Narasappa


2 Answers

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");
like image 172
Ali Soltani Avatar answered Nov 06 '22 17:11

Ali Soltani


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.

like image 2
toto Avatar answered Nov 06 '22 19:11

toto