7

我有一个网页,用户可以通过 ASP.NET Web 处理程序 ( .ashx) 下载 PDF 文件。它的实现方式与此问题中的答案类似。我遇到的问题是,当我在 JavaScript 中执行此window.top.location.href = url;操作时,如果处理程序中抛出异常,我无法真正控制会发生什么。当一切正常时,用户体验是他们基本上停留在他们所在的页面上,并且浏览器告诉他们他们可以下载 PDF 文件。但是,当处理程序中抛出异常时,它们将被重定向到处理程序的 URL 并显示一个空白页面。

以下是一些示例代码,以使其更清晰:

JavaScript:

function openPDF() {
    var url = GeneratePDFUrl();
    window.top.location.href = url;
}

处理程序:

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);
}

当 GetPDFData() 抛出异常时,就会出现问题。我们正在尽我们所能防止 GetPDFData() 抛出异常,但它是从用户输入生成的,因此我们也在此处处理它,以防出现我们无法/无法预测哪些情况会产生错误。

这是我提出的一种解决方案,但它显示了用户错误文本(而不是空白页)

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));
    }
}

理想情况下,我想向用户显示一个弹出窗口,以便他们留在他们所在的页面上。

4

2 回答 2

7

首先,在我的这个答案中,用户询问如何使用 javascript 进行下载。但是,如果您有不需要将其添加到 javascript 的链接,您也可以使用常规下载链接添加它。

现在许多网站使用带有一些文字的页面,上面写着“现在您的下载将在几秒钟内开始。如果没有开始,请点击这里 bla bla bla ”。原因之一与您的类似,用户必须知道某些内容将在几秒钟内开始下载,如果没有,那么用户就会理解存在其他额外消息的问题。

通常,当您要发送文件进行下载时,您不再位于页面中,您无法在下载过程中发送消息,或者当文件以 pdf 结尾时,可能不会显示任何内容在网页上。因此,从我的角度来看,如果您确实遇到问题并抛出异常,您需要设计一些步骤来告知用户出现问题 - 例如通知用户“现在您将收到文件的中间页面” - 如果文件在几秒钟内没有开始下载,请这样做“

但是,当处理程序中抛出异常时,它们将被重定向到处理程序的 URL 并显示一个空白页面。

为避免出现该黑页,您可以在出错时返回该代码,并且用户保持在页面上,但仍然没有收到任何错误消息。

Response.TrySkipIisCustomErrors = true;
Response.Status = "204 No Content";
Response.StatusCode = 204;
Response.End();

异常的替代方法,您可以尝试使用以下命令将他重定向到错误页面

Response.Redirect("errorpage.aspx");

也许你可以在那里发送一些错误ID。

您也可以尝试仅显示一条简单的消息

context.Response.ContentType = "text/html";
context.Response.Write("Error downloading file - Please contact with us");
于 2013-01-31T00:05:44.327 回答
3

如何设置隐藏 iframe 的 src 而不是设置窗口的 href。然后,您可以对隐藏 iframe 中的返回值做一些诡计,例如:

context.Response.Clear();
context.Response.Write("<script>alert('" + GetErrorMessage(e) + "');</script>");

这个粗略的例子只会提醒错误消息。如果你在同一个域上(我怀疑你是!)那么你可以变得更聪明,而不是警报,调用父级中的方法,例如

context.Response.Clear();
context.Response.Write("<script>window.parent.someFunction('" + GetErrorMessage(e) + "');</script>");

这是我在这样做时发现的一个示例:Retrieving HTTP status code from loaded iframe with Javascript

它是用于上传,而不是下载,而是相同的概念。

于 2013-01-30T17:00:46.190 回答