使用XMLHttpRequest和通用处理程序通过FTP下载PDF文件

5

我正在尝试使用Jquery Ajax请求从FTP服务器下载PDF文件。我参考了 http://www.dave-bond.com/blog/2010/01/JQuery-ajax-progress-HMTL5/

以下是我的Jquery ajax调用:

 $.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
                 }
             });

以下是我的C#通用处理程序代码,用于下载文件

  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;

            }
        }

当我运行代码时,文件可以下载到文件夹中而不会出现任何问题,在Ajax调用时
if (evt.lengthComputable) {
}

当我控制台打印evt时,我得到了下面的结果
enter image description here 总是返回false,因此我无法跟踪进度。

1)代码有什么问题吗?
2)是否有其他方法在下载PDF时显示进度条?


请查看此答案:https://dev59.com/3HDYa4cB1Zd3GeqPGf6p您的下载器需要输出“Content-length”头。从逻辑上讲,如果您不知道总文件大小,如何知道已下载的百分比呢? - dkasipovic
通用处理程序C#代码可以将文件下载到本地目录,没有任何问题,唯一需要做的就是在下载过程中显示进度条。 - Narasappa
你应该使用 content-length 来提供文件。请查看 https://dev59.com/Ol8d5IYBdhLWcg3w21Sm 并调整你的代码。 - Tarun Lalwani
你是否在互联网上搜索过或者遇到过这个链接?https://dev59.com/mmcs5IYBdhLWcg3w3HoG - CME64
2个回答

3
对于上传的字节,很容易显示进度条。只需监视xhr.upload.onprogress事件。浏览器知道它要上传的文件的大小和已上传数据的大小,因此可以提供进度信息。
对于下载的字节,有点更难,因为在这种情况下,浏览器所知道的唯一事情是它正在接收的字节数。
引起evt.lengthComputable为0的原因是浏览器不知道将发送多少字节的服务器请求。
有一个解决方案,只需在服务器上设置Content-Length标头,以便获取浏览器将要接收的字节的总大小。
// 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");

2

您的JS代码看起来很好。 我不是C#程序员,但我观察到C#服务器端会下载FTP文件并将其保存到磁盘服务器,但从未响应/发送PDF二进制数据到JS端? 从JS端下载的大小为0字节,并且evt.lengthComputable始终为false / 0。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接