zoukankan      html  css  js  c++  java
  • 解决下载ftp文件过程中,浏览器直接解析文件(txt,png等)的问题

    推荐一款ftp客户端工具:iis7服务器管理工具
    IIs7服务器管理工具可以批量管理ftp站点,同时具备定时上传下载的功能。
    作为服务器集成管理器,它最优秀的功能就是批量管理windows与linux系统服务器、vps。
    能极大的提高站长及服务器运维人员工作效率。同时iis7服务器管理工具还是vnc客户端,服务器真正实现了一站式管理,可谓是非常方便。

    搭建了一个ftp服务器,供用户进行上传下载,在下载过程中发现,一些文件,例如txt,jpg,png,pdf等直接被浏览器解析了。在浏览器中显示其内容,没有下载。

    下面通过网上查询得到一些解决方法:

     最简单的方法:

    在txt文档上面,点击右键》链接另存为    就可以直接下载。

    1:修改ftp目录下的.htacess文件,这个文件主要做一些类型映射,使各个文件类型映射为  octet-stream 类型,这样浏览器就不能解析了。

         但是,我没有在ftp目录下发现该文件,通过filezilla连接服务器, filezilla>服务器>强制显示隐藏文件 ,也没有发现该文件。听说该文件是apache独有的,我用的是vsftpd服务器,不知道是否存在不一致,于是放弃。

    2:第二种方法

          使用ajax请求,将文件输出流(OutputStream)作为回调结果返回。

    html代码,   后台代码同第4中方法。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <script type="text/javascript" src="/js/jquery-3.0.0.min.js"></script>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <script>
        function link() {
            $.ajax({
                type: "get",        //请求方式
                url: "downloadFileByOutputStream",      //请求路径
                data: {
                    "filename":'homepage.png'           //请求参数
                     },
                async: true,                          //异步,(同步已经废弃,会报错)。
                success: function (flag) {         //请求成功,flag返回数据
                    if (flag != "") {             
                    console.log(flag);            //浏览器控制台打印数据
                           var obj = eval(flag);      //对数据进行转换
                           localStorage['UsertypeSelect']=JSON.stringify(obj);   //将返回的数据存储到本地。
                        };
                }
            });
    }
    </script>
    </head>
    <body>
        <a href="javascript:void(0)" onclick="link()">客户端下载OutputStream</a>  //调用上面的函数
    </body>
    </html>

    调用之后,发现数据乱码,  eval(flag)对返回数据转化失败。

     

    3:  使结果作为PrintWriter流作为回调结果,使用隐藏表单提交的方式对流进行回调。结果  txt,doc等字符文件能够下载,但是图片等字节文件不能下载。

            前端代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script type="text/javascript" src="/js/jquery-3.0.0.min.js"></script>
        <script>
        function download(){
        console.log('执行');
            downloadTemplate('/downloadFileByPrintWriter', 'filename', 'homepage.png');
        }
        function downloadTemplate(action, type, value){  //action 请求接口,  type : 后台接口需要的参数名,value 请求的参数值
        console.log(action);         
            var form = document.createElement('form');     //创建表单 
            document.body.appendChild(form);               
            form.style.display = "none";                 
            form.action = action;              //接口
            form.id = 'download';              //表单id
            form.method = 'post';              //请求方式
    
            var newElement = document.createElement("input");     //创建元素,类型为input
            newElement.setAttribute("type","hidden");             //隐藏
            newElement.name = type;                               //元素名为type
            newElement.value = value;                             //元素值 value
            form.appendChild(newElement);                 
            form.submit();                                         //提交
        }
        </script>
    </head>
    <body>
    
    <span onclick="download()">客户端下载PrintWriter</span>
    
    </body>
    </html>

    后台代码:

       /**
         * 根据给定的文件名进行下载
         * Description: 从FTP服务器下载文件
         * @param filename 要下载的文件名
         * @return
         */
        @RequestMapping("/downloadFileByPrintWriter")
        @ResponseBody
        public String downloadFileByPrintWriter(HttpServletResponse response, String filename) throws IOException {
            FTPClient ftp = new FTPClient();
            try {
                int reply;
                ftp.connect(host, port);
                ftp.login(username, password);// 登录
                ftp.enterLocalPassiveMode();  //将ftp设置为被动模式。否则不成功。
    
                reply = ftp.getReplyCode();
                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftp.disconnect();
                    return "ftp无连接";
                }
                ftp.changeWorkingDirectory(publicFilePath);// 转移到FTP服务器目录
                logger.debug("远程路径" + publicFilePath);
                FTPFile[] fs = ftp.listFiles();
                for (FTPFile ff : fs) {
                    logger.debug("远程文件名" + ff.getName());
                    if (ff.getName().equals(filename)) {
                        InputStream in = ftp.retrieveFileStream(ff.getName());     //读取ftp服务器文件,返回输入流
                        int len = 0;
                        byte[] buff = new byte[1024];
                        response.reset();                   //重置响应
                        response.setContentType("application/octet-stream");      //设置响应类型为流类型
                        response.addHeader("Content-Disposition", "attachment; filename="" + filename + """);    //文件名
                        InputStreamReader inputStreamReader = new InputStreamReader(in);
    
                        PrintWriter fw = response.getWriter();            //得到response的字符打印流
    
                        //创建一个rd的字符留缓冲区,将字符装载入缓冲区中
                        BufferedReader bf = new BufferedReader(inputStreamReader);
                        char[] chs = new char[1024];
    //                    while ((len = bf.read(chs)) != 0) {
    //                        logger.debug("向fw写入");
    ////                        fw.write(chs, 0, len);
    //                    }
                        String str=null;
                        while ((str = bf.readLine()) != null) {
                            fw.write(str);                      //将ftp输入流写出到printWriter  
                            fw.flush();
                        }
                        fw.flush();
                        in.close();
                        fw.close();
                        return "成功";
                    }
                }
                ftp.logout();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (ftp.isConnected()) {
                    try {
                        ftp.disconnect();
                    } catch (IOException ioe) {
                    }
                }
            }
            return "下载失败";
        }

    4:将文件作为OutputStream流作为回调结果,使用隐藏表单提交的方式对流进行回调。成功

     html代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script type="text/javascript" src="/js/jquery-3.0.0.min.js"></script>
        <script>
        function download(){
        console.log('执行');
            downloadTemplate('/downloadFileByOutputStream', 'filename', 'homepage.png');
        }
        function downloadTemplate(action, type, value){
        console.log(action);
            var form = document.createElement('form');
            document.body.appendChild(form);
            form.style.display = "none";
            form.action = action;
            form.id = 'download';
            form.method = 'post';
    
            var newElement = document.createElement("input");
            newElement.setAttribute("type","hidden");
            newElement.name = type;
            newElement.value = value;
            form.appendChild(newElement);
            form.submit();
        }
        </script>
    </head>
    <body>
    
    <span onclick="download()">客户端下载PrintWriter</span>
    
    </body>
    </html>

    后台代码:

      /**
         * 根据给定的文件名进行下载
         * Description: 从FTP服务器下载文件
         * @param filename 要下载的文件名
         * @return
         */
        @RequestMapping("/downloadFileByOutputStream")
        @ResponseBody
        public String downloadFileByOutputStream(HttpServletResponse response, String filename) throws IOException {
            logger.debug("下载ByOutputStream");
            FTPClient ftp = new FTPClient();
            try {
                int reply;
                ftp.connect(host, port);
                // 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
                ftp.login(username, password);// 登录
                ftp.enterLocalPassiveMode();  //将ftp设置为被动模式。否则不成功。
                reply = ftp.getReplyCode();
                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftp.disconnect();
                    return "连接失败";
                }
                ftp.changeWorkingDirectory(publicFilePath);// 转移到FTP服务器目录
                logger.debug("远程路径" + publicFilePath);
                FTPFile[] fs = ftp.listFiles();
                for (FTPFile ff : fs) {
                    logger.debug("远程文件名" + ff.getName());
                    if (ff.getName().equals(filename)) {
                        InputStream in = ftp.retrieveFileStream(ff.getName());
                        logger.debug(in.toString());
                        int len = 0;
                        byte[] buff = new byte[1024*1024];
    
                        response.reset();
                        response.setContentType("application/octet-stream");
                        //Name the file
                        response.addHeader("Content-Disposition", "attachment; filename="" + filename + """);
    //                    response.addHeader("Content-Length", out..ToString());
                        OutputStream out=response.getOutputStream();  //响应输出字节流
    
    //                    OutputStream out = new PipedOutputStream();
                        while((len=in.read(buff))!=-1){
                            logger.debug("以字节流形式写出OutPutStream");
                            out.write(buff, 0, len);
                            out.flush();
                        }
                        in.close();
                        out.close();
                        return "成功";
                    }
                }
    
                ftp.logout();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (ftp.isConnected()) {
                    try {
                        ftp.disconnect();
                    } catch (IOException ioe) {
                    }
                }
            }
            return "失败";
        }
  • 相关阅读:
    线程安全,syncronized 用法
    线程
    Log4j2
    线性规划
    不要在using语句中调用WCF服务
    kibana 查询语法
    ES中DSL查询相关
    ES通过API调整设置
    ElasticSearch架构思考(转)
    Elasticsearch集群UNASSIGNED
  • 原文地址:https://www.cnblogs.com/liyafei/p/9296770.html
Copyright © 2011-2022 走看看