javascript 从 ASP.NET Web 处理程序 (.ashx) 下载文件时的错误处理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14609389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Error handling when downloading file from ASP.NET Web Handler (.ashx)
提问by Steve
I have a web page which a user can download a PDF file via an ASP.NET web handler (.ashx
). It is implemented like the answer in this question. The problem I have is when I do do this window.top.location.href = url;
in my JavaScript I have no real control over what happens if there is an exception thrown in the handler. The user experience, when everything works correctly, is that they essentially stay on the page they were on and the browser tells them that they can download the PDF file. However, when there is an exception thrown in the handler they are redirected to the URL of the handler and shown a blank page.
我有一个网页,用户可以通过 ASP.NET Web 处理程序 ( .ashx
)下载 PDF 文件。它的实现就像这个问题中的答案。我遇到的问题是,当我window.top.location.href = url;
在 JavaScript 中执行此操作时,如果处理程序中抛出异常,我无法真正控制会发生什么。当一切正常时,用户体验是他们基本上停留在他们所在的页面上,浏览器告诉他们他们可以下载 PDF 文件。但是,当处理程序中抛出异常时,它们会被重定向到处理程序的 URL 并显示一个空白页面。
Here is some example code to make it more clear:
下面是一些示例代码,以使其更清楚:
JavaScript:
JavaScript:
function openPDF() {
var url = GeneratePDFUrl();
window.top.location.href = url;
}
Handler:
处理程序:
public override void Process(HttpContext context)
{
byte[] pdfdata = GetPDFData();
context.Response.ContentType = "application/pdf";
context.Response.AddHeader("content-disposition", "attachment; filename=\"" + GetPDFFileName() + "\"");
context.Response.AddHeader("content-length", pdfdata.Length.ToString());
context.Response.BinaryWrite(pdfdata);
}
The problem happens when GetPDFData() throws an exception. We are doing what we can to prevent GetPDFData() from throwing an exception, but it is generated from user input so we're also handling it here in case there are cases we don't/can't predict which generate an error.
当 GetPDFData() 抛出异常时会出现问题。我们正在尽我们所能防止 GetPDFData() 抛出异常,但它是根据用户输入生成的,因此我们也在此处处理它,以防万一出现我们无法/无法预测哪个会产生错误的情况。
Here is one solution I have come up with, but it shows the user error text (instead of a blank page)
这是我提出的一种解决方案,但它显示了用户错误文本(而不是空白页)
public override void Process(HttpContext context)
{
try
{
byte[] pdfdata = GetPDFData();
WritePDF(pdfdata, GetPDFFileName()); // Executes code in example above
}
catch (Exception e)
{
context.Response.Clear();
context.Response.Write(GetErrorMessage(e));
}
}
Ideally I would like to show the user a popup so they stayed on the page they were.
理想情况下,我想向用户显示一个弹出窗口,以便他们停留在他们所在的页面上。
回答by Aristos
First of all on this answer of minethe user ask how to make the download with javascript. But if you have the link you do not necessary need to add it to javascript, you can add it also using a regular download link.
首先,在我的这个答案中,用户询问如何使用 javascript 进行下载。但是,如果您有链接,则无需将其添加到 javascript,您也可以使用常规下载链接添加它。
Now many web sites use a page with some text that says "and now your download will start in few seconds. If not start please click here bla bla bla". One of the reasons is similar to yours, the user must know that something will start the download in few seconds and if not, then the user understand that there is a problem with out other extra message.
现在许多网站都使用带有一些文字的页面,“现在您的下载将在几秒钟内开始。如果没有开始,请单击此处bla bla bla”。原因之一与您的类似,用户必须知道某些东西会在几秒钟内开始下载,如果没有,则用户知道存在问题,没有其他额外消息。
In general when you going to send a file for download, you are not in the page any more, you can not send message in the middle of the download, - or when the file ends with pdf, then is probably not going to show anything on a web page. So from my point of view if you do have issues and throw exceptions, you need to design some steps on how you inform the user that something was going wrong - like the middle page that inform the user that "now you going to receive a file - if the file not start the download in few seconds please do that"
通常,当您要发送文件进行下载时,您不再位于页面中,您无法在下载过程中发送消息,或者当文件以 pdf 结尾时,则可能不会显示任何内容在网页上。所以从我的角度来看,如果你确实有问题并抛出异常,你需要设计一些步骤来通知用户出现了问题——比如中间页面通知用户“现在你将收到一个文件- 如果文件在几秒钟内没有开始下载,请这样做"
However, when there is an exception thrown in the handler they are redirected to the URL of the handler and shown a blank page.
但是,当处理程序中抛出异常时,它们会被重定向到处理程序的 URL 并显示一个空白页面。
To avoid that black page, on error you can return that code and the user is stay on page as it is, but still did not get any error message.
为避免出现黑页,出现错误时您可以返回该代码,用户将原样留在页面上,但仍然没有收到任何错误消息。
Response.TrySkipIisCustomErrors = true;
Response.Status = "204 No Content";
Response.StatusCode = 204;
Response.End();
Alternative on exception you can try to redirect him to an error page using the
替代异常,您可以尝试使用以下命令将他重定向到错误页面
Response.Redirect("errorpage.aspx");
and maybe you can send and some error ids there.
也许你可以在那里发送一些错误 ID。
You can also try to just show a simple message as
您也可以尝试只显示一条简单的消息
context.Response.ContentType = "text/html";
context.Response.Write("Error downloading file - Please contact with us");
回答by Eli Gassert
How about instead of setting the href of the window, set the src of a hidden iframe. You can then do some trickery with the returned value in the hidden iframe, such as:
不如设置窗口的 href,设置隐藏的 iframe 的 src。然后,您可以对隐藏的 iframe 中的返回值进行一些操作,例如:
context.Response.Clear();
context.Response.Write("<script>alert('" + GetErrorMessage(e) + "');</script>");
This crude example would just alert the error message. If you're on the same domain (which I suspect you are!) then you can get more clever with, instead of alerting, calling a method in the parent, e.g.
这个粗略的例子只会提醒错误消息。如果你在同一个域(我怀疑你是!)那么你可以更聪明,而不是提醒,调用父级中的方法,例如
context.Response.Clear();
context.Response.Write("<script>window.parent.someFunction('" + GetErrorMessage(e) + "');</script>");
Here's an example I found on SO doing just this: Retrieving HTTP status code from loaded iframe with Javascript
这是我在 SO 上找到的一个示例:Retrieving HTTP status code from loaded iframe with Javascript
It's for an upload, not a download, but same concept.
它用于上传,而不是下载,而是相同的概念。