form提交后如何获取提交完成事件?

pig357 2015-08-24 02:18:26
加精
环境:asp.net C# vs2008
问题:点击页面上“导出”按钮,弹出“正在导出对话框”,然后使用form提交方式实现execl导出功能。现在导出功能完成了,就是不知道如何在导出后自动关闭遮罩层,也就是说不知道form提交完成事件是什么。

//通过form.submit的方式实现导出execl的功能
function _exportExecl(params){
...//弹出正在导出对话框
var downloadHelper = $('<iframe style="display:none;" id="downloadHelper"></iframe>').appendTo('body')[0];
var doc = downloadHelper.contentWindow.document;
if (doc) {
doc.open();
doc.write('')//微软为doc.clear()有时会出bug
doc.writeln("<html><body><form id='downloadForm' name='downloadForm' method='post' action='" + params.url + "'>");
for (var key in params)
doc.writeln("<input type='hidden' name='" + key + "' value='" + params[key] + "'>");
doc.writeln('<\/form><\/body><\/html>');
doc.close();
var form = doc.forms[0];
if (form) {
form.submit(); //提交表单后如何得到完成事件?
}
}
}

后台:

public void ProcessDownloadRequest(HttpContext context, Dictionary<string, string> dic)
{
.....//通过NPOI生成EXECL

#region 下载文件
Stream iostream = exporter.SaveAsStream();
byte[] buffer = new byte[iostream.Length];
iostream.Position = 0;
iostream.Read(buffer, 0, buffer.Length);
iostream.Close();

var res = HttpContext.Current.Response;
res.ContentType = "application/octet-stream";
//通知浏览器下载文件而不是打开
res.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(Decode("exportname"), System.Text.Encoding.UTF8));
res.BinaryWrite(buffer);
res.Flush();
res.End();
#endregion
}

我试着在ProcessDownloadRequest中添加context.Response.Write("导出成功"),结果连导出都没有了。。。
请问这个改怎么修改,当保存文件对话框显示时自动关闭遮罩?
...全文
20610 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
老衲是光头 2015-09-07
  • 打赏
  • 举报
回复
楼主解决没有啊,我做过类似的,也是导入到后台,不让用alert(),非要用自定义的弹出框,我是这么实现的

  Response.Write("<script> document.getElementById('myscript').innerHTML =setTimeout('myAlert(\"" + messon
                 + "\",function(){location.href=\"SubjectPlaceMent.aspx\";})',500); ;</script>");
    <script  type="text/javascript" id="myscript"></script>
将js代码加载到script标签中,延迟0.5秒加载(等html文档加载完成)后执行
游北亮 2015-09-06
  • 打赏
  • 举报
回复
同样也不理解这个问题为什么被推荐了??? 只要延时几秒,用js关闭遮罩层就ok的问题
robake 2015-09-01
  • 打赏
  • 举报
回复
为什么不用jquery ajax?jquery ajax里有success方法,这里直接写你完成后的代码就可以了。
su18709205730 2015-08-29
  • 打赏
  • 举报
回复
很不错!6666
吉普赛的歌 2015-08-27
  • 打赏
  • 举报
回复
1. 前台点击按钮, 发送 $.ajax 请求; 2. 后台生成 Excel 文件 , 并返回下载路径; 3. 前端接收到 结果, 打开返回的下载路径文件即可。 中间用一个 loading 图片即可, 非常简单。
java圈 2015-08-26
  • 打赏
  • 举报
回复
你可以用ajax,excel数据导出后会把结果返回到successfuly里面,可以根据这个结果判断
pig357 2015-08-26
  • 打赏
  • 举报
回复
引用 19 楼 sp1234_maJia 的回复:
方法1也最简单,但是提交整个页面。 如果你不希望提交刷新整个页面,那么其实你的所谓“遮罩层”的设计也就不太好。那么使用方法2就是最常见的做法,也就是说用户会看到弹出窗口(这个窗口会自动关闭,用不着遮罩层),但是用户又可以在原来页面上继续操作(而不会刷新、或者卡)。 如果3可能是你的问题的解决办法。但是你的问题中的代码其实不可取,甚至“使用iframe地方法”本身就不太可取,有些浏览器可能已经不支持它了。还是弹出系统内的另一个页面(并且浏览器会自动关闭它)更可取,并且各种浏览器都支持(包括各种手机上的 Hybride 应用的插件也支持你的 js 程序去打开另一个 WebView)。
谢谢各位大神了,经过测试我还是使用了方法3,因为任务赶的很,暂时先采用这种方法吧。

if (form) {
            form.submit();
            
            var icount = setInterval(function(){    
                if(doc.readyState != 'loading'){    //循环判断iframe状态,如果加载完成则表示开始了下载,此时关闭提示窗口
                    $.hideWaitForm();
                    clearTimeout(icount);
                }
            }, 1000);
        }
md5e 2015-08-25
  • 打赏
  • 举报
回复
js用parent 来操控父页关闭遮罩层
md5e 2015-08-25
  • 打赏
  • 举报
回复
Response.Write("<script>这里写结果的js,返回成功</script>"); Response.End();
qbilbo 2015-08-25
  • 打赏
  • 举报
回复
可以借鉴一下利用iframe实现异步上传的思路。 做一个隐藏的iframe接收post返回的页面,返回的页面里再调用原页面的js或直接进行后续操作。
sp1234_maJia 2015-08-25
  • 打赏
  • 举报
回复
方法1也最简单,但是提交整个页面。 如果你不希望提交刷新整个页面,那么其实你的所谓“遮罩层”的设计也就不太好。那么使用方法2就是最常见的做法,也就是说用户会看到弹出窗口(这个窗口会自动关闭,用不着遮罩层),但是用户又可以在原来页面上继续操作(而不会刷新、或者卡)。 如果3可能是你的问题的解决办法。但是你的问题中的代码其实不可取,甚至“使用iframe地方法”本身就不太可取,有些浏览器可能已经不支持它了。还是弹出系统内的另一个页面(并且浏览器会自动关闭它)更可取,并且各种浏览器都支持(包括各种手机上的 Hybride 应用的插件也支持你的 js 程序去打开另一个 WebView)。
  • 打赏
  • 举报
回复
按照上面方法1,就是当前页面刷新时执行下载,这时候只要在刷新前启动一个loading.....菊花即可。 按照上面方法2,那么你可以在脚本中监听或者轮询 window 的 Closed事件或者closed属性变化。 按照上面方法2,那么你可以在脚本中轮询 document 的 readyState 属性,或者响应的事件,或者其它对象的事件。
  • 打赏
  • 举报
回复
引用 11 楼 ajianchina 的回复:
这个帖子为何被推荐? 直接给你个连接 http://demo.jb51.net/js/2011/artDialog/index.html 中间有一段iframe嵌在层中,你看看层与层如何传值,还有看下调用的什么事件关闭层就好了,其实也是jQuery框架的延生,你下载他的js文件,再看下他的一些函数使用方法就行了。
lz 的问题,在你它弹出的是一个使用 res.BinaryWrite(buffer); res.Flush(); res.End(); 这样的代码的下载页,而不是普通的内容页面,因此它无法在其上再去写javascript代码去“传值、关闭”。
  • 打赏
  • 举报
回复
我们用传统的asp.net程序员来说明一下下载文件的机制,然后顺便说一下纯js脚本该如何做。 先随便做个测试,你随便在一个asp.net页面上,拖一个Button按钮,然后产生如下类似的下载文件代码:
protected void Button1_Click(object sender, EventArgs e)
{
    Response.Headers["Content-disposition"] = "attachment; filename=" + HttpUtility.UrlEncode("啦啦啦.txt");
    Response.TransmitFile(MapPath("~/app_data/swf.txt"));
    Response.End();
}
你可以看到,页面就可以下载“啦啦啦.txt”文件了。用不着另开一个窗口。如果要显示“正在下载.....”提示,那么找一个普通的we页面通用的loading....插件就行了。 如果你说“我就是非要让下载是另一个的页面”,那么你应该这样先创建一个专门用来下载的Download.ashx:

using System;
using System.Web;

public class TestDownload : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.Headers["Content-disposition"] = "attachment; filename=" + HttpUtility.UrlEncode("啦啦啦.txt");
        context.Response.TransmitFile(context.Server.MapPath("~/app_data/swf.txt"));
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}
然后你的页面弹出这个下载页
protected void Button1_Click(object sender, EventArgs e)
{
    var sc = string.Format("var ww= window.open('{0}');", ResolveUrl("~/TestDownload.ashx"));
    sc += "alert(ww.closed); setTimeout(function(){ alert(ww.closed);}, 1000);";
    ClientScript.RegisterStartupScript(this.GetType(), "dw", sc, true);
}
如果你实际测试一下,你会看到新打开的下载页的时候,首先ww的closed属性是false,然后当下载开始之后,它的closed属性就迅速变为true了。 实际上 ww 的 Closing事件、Unload事件、Closed 事件也会触发。 实际的js代码中,你可以监听事件,或者监听这个属性变化,或者使用一个定时器来循环检测一下这个属性的变化。 如果一定要写 IFrame 代码,看看这样的例子:
<body>
    <form id="form1" runat="server">
                  .........这里有一个Button按钮
    <iframe id="download" src="#" runat="server" style="display: none;"></iframe>
    </form>
</body>
protected void Button1_Click(object sender, EventArgs e)
{
    this.download.Attributes["src"] = ResolveUrl("~/TestDownload.ashx");
}
(注意iframe写在<form runat="server">内部) 并且 Download.ashx的内容是
<%@ WebHandler Language="C#" Class="TestDownload" %>

using System;
using System.Web;

public class TestDownload : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.Headers["Content-disposition"] = "attachment; filename=" + HttpUtility.UrlEncode("啦啦啦.txt");
        context.Response.TransmitFile(context.Server.MapPath("~/app_data/swf.txt"));
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}
然后页面下载按钮可以写
protected void Button1_Click(object sender, EventArgs e)
{
    this.download.Attributes["src"] = ResolveUrl("~/TestDownload.ashx");
    var sc = "var dd= frames['download'].window.document; alert(dd.readyState); setTimeout(function(){ alert(dd.readyState);}, 1000); setTimeout(function(){ alert(dd.readyState);}, 10000);";
    ClientScript.RegisterStartupScript(this.GetType(), "dw", sc, true);
}
如果你只是js,其实是一样的。看懂了上面的,就知道如何在javascript端获取下载结果了。
sy401042879 2015-08-25
  • 打赏
  • 举报
回复
可以这样。在后台最后在输出导出完成的字符串,前台截取、提取这个字符串即可!
qbilbo 2015-08-25
  • 打赏
  • 举报
回复
引用 14 楼 qbilbo 的回复:
不好意思,前面回复时只看了标题,没看仔细看内容。 你这个问题其实应该是怎样判断开始下载。 据我所知,JS里没这个事件,用ajax的话,datatype貌似没有stream这种类型,最关键的是js也不能在本地写文件。 我能想到的方案有2个: 1,submit后延迟几秒关闭遮蔽层,具体延迟几秒,可以测试一下,比服务端平均返回时间稍微大一点就行。 2,把服务端下载分成2个方法,方法1:先生成文件流,再用guid设置一个id在session中缓存,返回给客户端一个json对象。(比如:{"success":true,"id":"xxx"}或:{"success":flase,"error":"xxx"}),方法2:根据key来下载文件。这样客户端的js就很好写了。 个人觉得大部分情况下用方法1就行了。
2,把服务端下载分成2个方法,方法1:先生成文件流,再用guid设置一个id在session中缓存,返回给客户端一个json对象。(比如:{"success":true,"id":"xxx"}或:{"success":false,"error":"xxx"}),方法2:根据id来下载文件。这样客户端的js就很好写了。 前面有些拼写错误。
qbilbo 2015-08-25
  • 打赏
  • 举报
回复
不好意思,前面回复时只看了标题,没看仔细看内容。 你这个问题其实应该是怎样判断开始下载。 据我所知,JS里没这个事件,用ajax的话,datatype貌似没有stream这种类型,最关键的是js也不能在本地写文件。 我能想到的方案有2个: 1,submit后延迟几秒关闭遮蔽层,具体延迟几秒,可以测试一下,比服务端平均返回时间稍微大一点就行。 2,把服务端下载分成2个方法,方法1:先生成文件流,再用guid设置一个id在session中缓存,返回给客户端一个json对象。(比如:{"success":true,"id":"xxx"}或:{"success":flase,"error":"xxx"}),方法2:根据key来下载文件。这样客户端的js就很好写了。 个人觉得大部分情况下用方法1就行了。
pig357 2015-08-25
  • 打赏
  • 举报
回复
求帮助啊大神们!
  • 打赏
  • 举报
回复
是 asp.net mvc 吗?
加载更多回复(4)

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧