PDF下载后执行Response.Redirect报错,求正确跳转方法
解决PDF下载完成后跳转thankyou.html的问题
你遇到的这两个错误其实都是HTTP响应机制导致的:
- 当你调用
Response.BinaryWrite(data)和Response.Flush()后,HTTP响应的头部和部分内容已经发送到客户端了,这时候再调用Response.Redirect就会触发Cannot redirect after HTTP headers have been sent——因为HTTP协议要求跳转的302状态码必须在响应内容之前发送。 - 如果把
Response.Redirect移到Response.Flush之前,Response.Redirect默认会调用Response.End()终止当前线程,导致后续的下载逻辑根本不会执行,同时线程被强制终止就会出现Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack错误。
正确的实现思路
后端在发送下载流之后,无法再修改HTTP响应来触发跳转,所以最优方案是让前端来处理下载后的跳转,这里给你两种可行的实现方式:
方式一:后端返回触发下载+跳转的脚本
修改你的download()方法,不直接发送PDF二进制内容,而是输出一段HTML脚本,让客户端自动触发下载并跳转:
protected void download() { try { string pdfRelativePath = "pdf/myDoc.pdf"; string path = Server.MapPath(pdfRelativePath); System.IO.FileInfo file = new System.IO.FileInfo(path); if (file.Exists) { Response.Clear(); Response.ContentType = "text/html"; // 输出脚本:先触发下载,延迟1秒后跳转(可根据需要调整延迟时间) Response.Write(@" <!DOCTYPE html> <html> <body> <script> // 触发PDF下载 window.location.href = '" + pdfRelativePath + @"'; // 延迟跳转,给浏览器处理下载请求的时间 setTimeout(() => { window.location.href = 'thankyou.html'; }, 1000); </script> </body> </html> "); Response.End(); } else { Response.Write("This file does not exist."); } } catch (Exception ex) { // 注意转义单引号,避免脚本语法错误 string escapedMsg = ex.Message.ToString().Replace("'", "\\'"); ScriptManager.RegisterStartupScript(this, GetType(), "showalert", $"alert('{escapedMsg}');", true); } }
方式二:前端通过隐藏iframe触发下载,直接跳转
保持你原来的download()方法(去掉Response.Redirect那一行),然后在前端页面用JavaScript处理下载和跳转:
function startDownload() { // 创建隐藏的iframe来加载下载链接,避免当前页面被下载请求占用 const downloadIframe = document.createElement('iframe'); downloadIframe.style.display = 'none'; // 替换成你的download方法对应的请求地址 downloadIframe.src = 'YourPage.aspx?action=download'; document.body.appendChild(downloadIframe); // 立即跳转到感谢页面 window.location.href = 'thankyou.html'; }
然后把你的下载按钮绑定这个startDownload()方法即可。
这两种方法都能完美解决你遇到的问题,确保用户既能正常下载PDF,又能跳转到感谢页面。
内容的提问来源于stack exchange,提问作者Tushar
相关产品推荐
相关产品推荐

