最近在项目中经常用到模态窗口(showModalDialog),客户需要在一个模态窗口中有"生成Excel报表"并"导出"的功能。
?
功能的设计思路是这样的:
1、首先在主窗口收集一些需要的数据
2、showModalDialog,将收集的数据传递过去,在模态页面使用window.dialogArguments接收这些参数
3、在模态页面收集客户的个性化定制信息
4、客户点击模态页面上的提交按钮,页面将请求通过Ajax异步方式提交到后台,生成文件,返回文件在服务器上的绝对路径
5、模态页面将内置的一个隐藏的iframe的src先置空,然后将文件路径作为参数传给下载页面,通过流方式下载文件
?
把基本流程完成之后,测试一下。点击提交按钮,前台没有任何反应。根据后台日志,又确定文件已经生成、成功读取并往流中写出了。
这是什么原因呢?
Google了很久,基本上只有以下两种答案:
?
1、模态窗口的定向问题
?
引用页:http://hi.baidu.com/037123/blog/item/e379854da9d561f3d62afc0c.html
showDialog里好像不能用href,只能用onclick
最近在项目中经常用到模态窗口(showModalDialog),客户需要在一个模态窗口中有"生成Excel报表"并"导出"的功能。接到任务后,直接就开始按常规操作实现。
??? 在按钮的Click事件中,根据模板生成Excel报表,填充数据,保存到临时文件夹,然后用Response.WriteFile函数输出文件,一切看上去都很顺利。代码如下:
??????????? //根据数据集创建Excel报表并返回Excel报表路径
??????????? string fileName = CreateExcel(ds);
??????????? Response.Clear();
??????????? Response.Charset = "utf-8";
??????????? Response.Buffer = true;
??????????? this.EnableViewState = false;
??????????? Response.ContentEncoding = System.Text.Encoding.UTF8;
??????????? Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
??????????? //设置输出文件类型为excel文件。?
??????????? Response.ContentType = "application/ms-excel";
??????????? Response.WriteFile(fileName);
??????????? Response.Flush();
??????????? Response.Close();
??????????? Response.End();
??? 但是当完成了代码,开始测试的时候,却发现点击"导出"按钮没有反应。开始的时候以为是创建Excel报表的代码有问题,但经过调试后,证实创建Excel代码没有问题,也成功的在临时文件夹下生成了Excel报表,但是却没有"导出"报表(没弹出下载文件对话框)。再看输出文件的代码,应该也没有问题,之前一直这样输出都没有问题的。
??? 在百思不得其解的时候,发现了一个关键点。就是之前输出文件成功的面页都是一般的网页窗口,而这次的操作却是在模态窗口中。问题会不会出在这里呢?赶紧试验了一下。把模态窗口改成了一般的网页窗口,果然可以输出文件没问题,也成功下载了报表。
??? 虽然问题有点怪异,但找到了切入点和问题的关键所在,解决应该就不难了。google一下,发现模态窗口定义了<base target="_self">,这应该是问题所在。然后在页面中重新定义了这个标签,改成了<base target="_blank">,问题成功解决,文件可以正常下载了。但这时候又来了新的问题,下载是可以了,但是却会弹出一个新页面,在模态窗口中下载再弹出页面肯定影响了用户体验。有没有方法在模态窗口中直接下载而不弹出新的页面呢?既然target=_self的时候有问题,target=_blank的时候又会弹出新的页面,这让我想到了在框架中打开新窗口的做法。在页面中加一个看不到的框架,然后把target设为框架名应该可以解决。随后在页面中再加了一个大小为0的iframe
<iframe id="download" name="download" height="0px" width="0px"></iframe><!--用iframe模拟文件下载-->
然后重新修改<base>标签target为框架名:
<base target="download">
重新生成,浏览,测试。问题成功解决。
?
?
2、JS脚本问题
?
引用页:http://hi.baidu.com/%C0%D6%D0%CD%D5%DF/blog/item/f5422a11311f60d3a6ef3fc1.html
var obj=document.getElementById(‘download’);
obj.contentWindow.location.href=http://sunyoush.iteye.com/blog/url;
?
?
这两种方式我都试过了,都不行。最后功夫不负有心人,在Windows的升级信息中找到了答案:
主要是浏览器对于异步访问的问题,将原来的异步调用改成同步调用的,就可以了
?
引用页:http://bbs.blueidea.com/viewthread.php?tid=1708871&page=
?
如果异步请求信息,您的 Web 站点是否会打开一个新窗口?
如果站点在异步请求信息后打开特定的窗口,则 Internet Explorer 可能会阻止这些窗口,即使用户单击了链接以打开该窗口。如果在请求异步信息之前,直接从用户启动的操作(鼠标单击)打开窗口,那么这些窗口不会被阻止。用户启动的操作不能跨导航保持。
?