IO记录,iframe实现无刷新下载

1 篇文章 0 订阅
1 篇文章 0 订阅
本文介绍了如何使用iframe实现无刷新下载,解决了ajax下载时浏览器无法显示“打开”或“保存”对话框的问题。文章详细阐述了通过jsp、js和web层的三个关键步骤来实现这一功能,并对比了使用ajax的错误做法。此外,还提到了隐藏iframe以及在iframe中打开页面的方法。
摘要由CSDN通过智能技术生成

一、IO比较常用的写法,可以在此基础上进行扩展。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;


public class IOTests {
	public static void main(String[] args)  {
		File file = new File("c:/upload");
		if(!file.exists()){
			file.mkdir();
		}
		try {
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:/upload/a.txt"));//使用了装饰者模式增加缓冲区
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("d:/ggg.txt")));
			
			byte[] buffer = new byte[512];//缓冲区为512字节
			int len = -1;
			while((len = bis.read(buffer)) != -1){
				bos.write(buffer,0,len);
			}
			bos.flush();
			bos.close();
			bis.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

二、通过iframe来实现无刷新下载

由于在下载的过程中需要传递一个动态参数给后台作为文件名,而且下载的时候不能刷新页面,刚开始的想法是使用ajax来进行文件的下载,过程也挺顺利的,可是在点击下载之后浏览器没有提示是否进行“打开”或者是“保存”的窗口,下载的文件也不知道到哪里去了,觉得很奇怪,折腾了一天终于有点眉目:

原因:ajax只能获取到string类型的内容,只能处理文本信息,不能处理二进制信息,所以在下载中设置response.setHeader("Content-Disposition", "attachment;filename=" + outputFilename)之后浏览器无法识别此时的类型是否是文件流的形式,如果使用firebug看一下这个ajax请求的响应结果的话,会看到一段乱码,因为ajax无法处理文件流的格式,所以不能用ajax来作无刷新页面下载。此时可以使用超链接或者iframe+表单的方式来实现无刷新下载。由于在超链接中传递动态参数觉得比较麻烦,所以我选用第二种方式来实现。关键步骤如下:

(1)jsp页面:

<div style="display: none">
				<iframe  name="download_print_template_form_iframe" style="width: 1px; height: 0px;" ></iframe>
			</div>
			<form id="print_form" action="/web/basicdata/printtemplate/download.action" method="post" target="download_print_template_form_iframe">
			
				<input type="hidden" id="downloaduuid" name="downloaduuid" value="" />
				
				<input type="button" id="btn_download" value="下载" />
			</form>

这里主要是定义了一个隐藏的iframe和一个普通的表单,这两个的关联在于:form必须写一个target属性,这个属性的值必须和iframe的name属性的值一样,其他就没有了。

(2)js处理:

 $("#btn_download").click(function(){
		 var uuid = bean.uuid;
		 $("#downloaduuid").val(uuid);
		 $("#print_form").submit();
	 });
这里其实就是提交表单,只不过我需要传递一个uuid过去作为文件名,所以我在这里多设置了一下
<input type="hidden" id="downloaduuid" name="downloaduuid" value="" />这个隐藏域的值,

(3)web层:

@RequestMapping(value = "/download")
	public void download(String downloaduuid, HttpServletResponse response) {
		System.out.println("downloaduuid为:" + downloaduuid);
		InputStream InputStream = fileService.downFile("cd_print_template", downloaduuid, downloaduuid);//downFile封装了普通下载的写法
		downloadFile(InputStream, response, downloaduuid);
		System.out.println("下载成功!");
	}

	/**
	 * 
	 * 设置浏览器信息
	 * 
	 * @param is
	 * @param response
	 * @param filename
	 */
	public static void downloadFile(InputStream is, HttpServletResponse response, String filename) {
		String outputFilename = filename;
		try {
			outputFilename = URLEncoder.encode(filename, Encoding.UTF8.getValue());
			//outputFilename = MimeUtility.encodeWord(filename);
		} catch (UnsupportedEncodingException e2) {
			e2.printStackTrace();
		}
		response.reset();
		response.setCharacterEncoding(Encoding.UTF8.getValue());
		response.setContentType("application/msword; charset=UTF-8");
		response.setHeader("Content-Disposition", "attachment;filename=" + outputFilename + ".doc");
		OutputStream os = null;
		try {
			os = response.getOutputStream();
			IOUtils.write(IOUtils.toByteArray(is), os);
		} catch (Exception e) {
			e.printStackTrace();
			try {
				if (os != null) {
					os.write(e.getMessage().getBytes());
				}
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		} finally {
			if (is != null) {
				IOUtils.closeQuietly(is);
			}
		}
	}

好了,通过以上3个步骤,既可以实现无刷新下载

附注:

(1)使用ajax的错误写法:

 $("#btn_download").click(function(){
    	 jQuery.ajax({ 
    		   type: "GET",
    		   url: ctx + '/basicdata/printtemplate/download.action',
    		   data: "uuid="+bean.uuid,
    		   dataType: "text",
    		   success: function(msg){
    			   alert("下载成功!");
    		   }, error    : function(result) {
   				alert("下载失败!");
   			}

    			
    		  });
    });

(2)这里使用的是SpringMVC,所以response对象直接在控制层写 HttpServletResponse response即可得到,如果是在struts2中,就按照struts2的获取response对象的方法来获取即可。

三、隐藏iframe的方法

<iframe width=0 height=0 frameborder=0>
iframeId.style.display="none";//iframeid为iframe的id

四、在iframe框架中打开页面的方法
只要设置链接的target属性值与目标框架名一样就行了。 
具体步骤: 
1:对于frameset对象。 
(1)包含框架页的代码。 

<frameset cols="100,*" name="frame1"> 
<frame src="1.htm" name="top"> 
<frame src="2.htm" name="main"> 
</frameset> 
(2)框架加载页(1.htm或2.htm)的链接代码: 
<a href="http://www.flash8.net" target="top">在上框中打开链接</a> 
<a href="http://www.flash8.net" target="main">在主框中打开链接</a> 
2.对于iframe也是一样的用法。 
<iframe src="about:blank" name="left"></iframe> 
<iframe src="about:blank" name="right"></iframe> 
<a href="http://www.flash8.net" target="left">在左框中打开链接</a> 
<a href="http://www.thugx.com" target="right">在右框中打开链接</a> 
技巧:在用脚本中设置目标框架的location属性值也可以达到同样的目的。如: 
<a href="http://www.flash8.net" 
onClick="document.frames[’right’].location=this.href;return false">在名为right的框架中打开链接</a> 
参考链接: http://www.jb51.net/web/23407.html







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值