ASP.NET UpdatePanel下PDF下载功能UpdateProgress控件无法自动隐藏问题
问题根源
首先明确你遇到的两个问题的本质原因:
- 异步PostBack(
AsyncPostBackTrigger)时无法下载PDF:AJAX请求返回的二进制流无法触发浏览器的默认下载行为,浏览器不会将异步请求拿到的文件流识别为可下载的附件。 - 同步PostBack(
PostBackTrigger)时加载图标无法隐藏:同步回发后你在服务端调用了Response.End(),直接终止了页面的后续渲染流程,页面不会刷新,你通过JS手动显示的加载图标没有被触发隐藏的逻辑,因此一直停留。
解决方案一:Cookie标记法(改动最小,兼容现有逻辑)
该方案无需修改现有回发逻辑,通过服务端写入下载完成标记Cookie,前端轮询Cookie判断下载状态。
1. 修改后台mtdCreatePDF方法
在Response.End()前添加Cookie标记,标识PDF生成完成:
if (TypeOutput == "RESPONSE") { Response.Clear(); Response.ClearContent(); Response.ClearHeaders(); Response.ContentType = "application/pdf"; Response.AddHeader("content-disposition", "attachment;filename=print.pdf"); Response.Cache.SetCacheability(HttpCacheability.NoCache); // 新增下载完成标记Cookie Response.Cookies.Add(new HttpCookie("PDFDownloadCompleted", "1") { Path = "/" }); Response.BinaryWrite(stream.ToArray()); Response.End(); }
2. 修改Test.js代码
在显示加载图标后,开启定时器轮询Cookie,检测到完成标记后隐藏加载图标:
function postbackButtonClick() { const updateProgress = $find("UpdateProgress2"); window.setTimeout(function () { updateProgress.set_visible(true); // 每500ms轮询一次Cookie状态 const checkTimer = setInterval(function() { const cookieList = document.cookie.split('; '); const completedFlag = cookieList.find(item => item.startsWith('PDFDownloadCompleted=')); if (completedFlag && completedFlag.split('=')[1] === '1') { // 隐藏加载图标 updateProgress.set_visible(false); // 清除已使用的Cookie document.cookie = "PDFDownloadCompleted=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT;"; // 停止轮询 clearInterval(checkTimer); } }, 500); }, 100); return true; }
解决方案二:iframe异步下载(体验更好,无整页回发)
如果你希望避免整页同步回发的卡顿,可以改用隐藏iframe实现无感知下载:
- 将PDF生成逻辑迁移到独立的一般处理程序
GeneratePDF.ashx中,接收参数后直接返回PDF文件流。 - 修改前端按钮的点击逻辑,取消回发,动态创建隐藏iframe触发下载,监听iframe加载完成事件隐藏加载图标:
function downloadPDF() { const updateProgress = $find("UpdateProgress2"); updateProgress.set_visible(true); // 动态创建隐藏iframe触发下载 const downloadIframe = document.createElement('iframe'); downloadIframe.style.display = 'none'; // 传递需要的参数,比如txtMat的输入值 const matVal = document.getElementById('<%= txtMat.ClientID %>').value; downloadIframe.src = `GeneratePDF.ashx?mat=${encodeURIComponent(matVal)}`; document.body.appendChild(downloadIframe); // 下载完成后隐藏加载并销毁iframe downloadIframe.onload = function() { updateProgress.set_visible(false); document.body.removeChild(downloadIframe); } return false; }
修改LinkButton的OnClientClick为return downloadPDF();,同时移除OnClick服务端事件和对应的PostBackTrigger即可。
内容的提问来源于stack exchange,提问作者Franco
相关产品推荐
相关产品推荐

