zoukankan      html  css  js  c++  java
  • 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://gist.github.com/DavidMah/3533415
    http://marcanguera.net/blog/2013/07/01/download-file-via-ajax/

  • 相关阅读:
    Head first javascript(七)
    Python Fundamental for Django
    Head first javascript(六)
    Head first javascript(五)
    Head first javascript(四)
    Head first javascript(三)
    Head first javascript(二)
    Head first javascript(一)
    Sicily 1090. Highways 解题报告
    Python GUI programming(tkinter)
  • 原文地址:https://www.cnblogs.com/nuccch/p/7151228.html
Copyright © 2011-2022 走看看