解决下载ftp文件过程中,浏览器直接解析文件(txt,png等)的问题

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

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

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 "失败";
    }

原文地址:https://www.cnblogs.com/liyafei/p/9296770.html

时间: 2024-10-01 20:07:45

解决下载ftp文件过程中,浏览器直接解析文件(txt,png等)的问题的相关文章

编译过程中,termcap.h 文件找不到路径 licli.a终于生成

编译过程中,termcap.h      文件找不到路径 查看是linux  源码下找不到termcap.h文件 安装了所有关于*cap*的源码包也不起作用 今天终于解决了这个问题,搜termcap.h  发现一篇文章,如下 ----------------------------------------------------------------------------------------- 安装minicom2.3出现termcap.h错误解决方法 2010-05-06 17:12:

C++中读写文件过程中异常处理机制

在利用C++进行文件读取与写入过程中,无论是针对二进制文件还是文本文件均需要进行异常处理,在C++中我们可以利用CFile进行文件的读写,而在MFC中还可以利用CStdioFile进行文件的读写. 利用CFile进行读文本文件过程中的异常处理可以通过如下代码实现 CString m_strFileName = "test.txt"; CFile m_File; CFileException ex; if (!m_File.Open(m_strFileName,CFile::modeRe

使用ftp读取文件夹中的多个文件,并删除

public class FTPUtils { private static final Logger LOG = LoggerFactory.getLogger(FTPUtils.class); /** * 获取FTPClient对象 * * @param ftpHost FTP主机服务器 * @param ftpPassword FTP 登录密码 * @param ftpUserName FTP登录用户名 * @param ftpPort FTP端口 默认为21 * @return */ p

[003]从文件夹中读取所有图片或者文件

从javascript的角度上看,因为语言的关系,是不能从文件夹读取文件的. 但是,我们可以同activeX的方法来获取后,传递给javascript使用. 详细代码如下: 1 var fileNameArray = []; 2 function searchFiles1(dir){ 3 if (dir.substr(dir.length-1, 1) != "\\" && dir.substr(dir.length-1, 1) != "/") 4 d

用字符流实现每个文件夹中创建包含所有文件信息的readme.txt

1 package com.readme; 2 3 import java.io.BufferedWriter; 4 import java.io.File; 5 import java.io.FileWriter; 6 import java.io.IOException; 7 import java.text.SimpleDateFormat; 8 import java.util.Date; 9 import java.util.Scanner; 10 11 /** 12 * @autho

.gitignore 规则写法 - 在已忽略文件夹中不忽略指定文件、文件夹【注意项】

1. 在已忽略文件夹中不忽略指定文件夹 /node_modules/* !/node_modules/layer/ 2. 在已忽略文件夹中不忽略指定文件 /node_modules/* !/node_modules/layer/layer.js [注意项]注意写法 要忽略的文件夹一定要结尾 /* ,否则不忽略规则将无法生效 3. 其他规则写法 (附) 以斜杠"/"开头表示目录: 以星号"*"通配多个字符: 以问号"?"通配单个字符 以方括号&qu

删除指定文件夹中除保留的文件外的所有文件批处理 删除指定文件夹下的空文件夹,包括子目录批处理

删除指定文件夹中除保留的文件外的所有文件批处理 @echo off set "ext= sln csproj" for /f "delims=" %%a in ('dir /b/s/a-d *.*') do ( set .= if /i not "%%~nxa"=="%~nx0" ( for %%i in (%ext%) do if /i "%%~xa"==".%%i" set .=.

java 复制文件夹中epub、html、txt文件 (按原来文件夹存放)

原来文件夹中的文件:有epub/html/txt import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * 复制文件夹中所有包含.epub后缀的文件 * @author fibre * parameter SUFFIX = ".epub&qu

在存放源程序的文件夹中建立一个子文件夹 myPackage。例如,在“D:\java”文件夹之中创建一个与包同名的子文件夹 myPackage(D:\java\myPackage)。在 myPackage 包中创建一个YMD类,该类具有计算今年的年份、可以输出一个带有年月日的字符串的功能。设计程序SY31.java,给定某人姓名和出生日期,计算该人年龄,并输出该人姓名、年龄、出生日期。程序使用YM

题目补充: 在存放源程序的文件夹中建立一个子文件夹 myPackage.例如,在"D:\java"文件夹之中创建一个与包同名的子文件夹 myPackage(D:\java\myPackage).在 myPackage 包中创建一个YMD类,该类具有计算今年的年份.可以输出一个带有年月日的字符串的功能.设计程序SY31.java,给定某人姓名和出生日期,计算该人年龄,并输出该人姓名.年龄.出生日期.程序使用YMD的方法来计算年龄. 主要考包的运用 用到java.util.Calendar