• ajax方式下载文件


    在web项目中需要下载文件,由于传递的参数比较多(通过参数在服务器端动态下载指定文件),所以希望使用post方式传递参数。
    通常,在web前端需要下载文件,都是通过指定<a>标签的href属性,访问服务器端url即可下载并保存文件到本地。
    但是这种方式使用的是HTTP GET方法,参数只能通过URL参数方式传递,无法使用POST方式传递参数。
    于是,想到使用ajax方式下载文件。

    实验:ajax方式下载文件时无法触发浏览器打开保存文件对话框,也就无法将下载的文件保存到硬盘上!
    原因:ajax方式请求的数据只能存放在javascipt内存空间,可以通过javascript访问,但是无法保存到硬盘,因为javascript不能直接和硬盘交互,否则将是一个安全问题。

    那么,如果想实现post方式提交参数下载文件,应该怎么实现呢?
    可以通过模拟表单提交的方式实现post传递数据。

    <div>
        <a href="<%=request.getContextPath()%>/ajaxDownloadServlet.do?fileName=testAjaxDownload.txt">同步下载文件</a><br />
        <a href="#" onclick="downloadFilebyAjax()">ajax下载文件</a> <br />
        <a href="#" onclick="downloadFileByForm()">模拟表单提交下载文件</a>
    </div>
    <script type="text/javascript">
        // 直接通过ajax请求文件数据
        // jquery下载文件时不能触发浏览器弹出保存文件对话框!
        // 可以在javascript中访问下载的文件数据
        function downloadFilebyAjax() {
            console.log("ajaxDownloadDirectly");
            var url = "http://localhost:8080/ajaxDownloadServlet.do";
            $.ajax({
                url: url,
                type: 'post',
                data: {'fileName': "testAjaxDownload.txt"},
                success: function (data, status, xhr) {
                    console.log("Download file DONE!");
                    console.log(data); // ajax方式请求的数据只能存放在javascipt内存空间,可以通过javascript访问,但是无法保存到硬盘
                    console.log(status);
                    console.log(xhr);
                    console.log("=====================");
                }
            });
        }
        
        // 模拟表单提交同步方式下载文件
        // 能够弹出保存文件对话框
        function downloadFileByForm() {
            console.log("ajaxDownloadSynchronized");
            var url = "http://localhost:8080/ajaxDownloadServlet.do";
            var fileName = "testAjaxDownload.txt";
            var form = $("<form></form>").attr("action", url).attr("method", "post");
            form.append($("<input></input>").attr("type", "hidden").attr("name", "fileName").attr("value", fileName));
            form.appendTo('body').submit().remove();
        }
    </script>

    servlet实现:

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        logger.info("ajax download file");
        String fileName = req.getParameter("fileName");
        File file = new File(System.getProperty("user.home"), fileName);
        
        resp.setContentType("application/octet-stream");
        resp.setHeader("Content-Disposition","attachment;filename=" + fileName);
        resp.setContentLength((int) file.length());
        
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            byte[] buffer = new byte[128];
            int count = 0;
            while ((count = fis.read(buffer)) > 0) {
                resp.getOutputStream().write(buffer, 0, count);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            resp.getOutputStream().flush();
            resp.getOutputStream().close();
            fis.close();
        }
    }

    参考原文:https://www.cnblogs.com/nuccch/p/7151228.html

  • 相关阅读:
    当今的架构师和架构
    外企2
    测试驱动开发TDD系列
    在IIS中部署WCF中遇到的问题
    设计高可用和高负载的网站系统(转载)
    IIS中部署WCF
    无限级分类1
    读《WCF技术剖析》(卷一)
    无限极列表2
    TCP/IP、HTTP、WEBSERVICE、SOAP、ICE都使用后才有感慨
  • 原文地址:https://www.cnblogs.com/wyhluckdog/p/10741103.html
Copyright © 2020-2023  润新知