【问题标题】:Detecting when a save as dialog is shown to the user检测何时向用户显示另存为对话框
【发布时间】:2021-10-25 02:53:28
【问题描述】:

我遇到了一个使用 ajax 调用(通过 jQuery)将辅助文件加载到 iframe 的 ASP.Net Webforms 应用程序的问题。这些辅助文件会压缩一堆文件,然后将它们流式传输给用户。我有一个显示加载动画的模态,但是当我将它设置为在 ajax 完成时将其删除时,有时仍需要几秒钟甚至更长的时间才能使模态消失。

这是按钮:

<asp:Button ID="btnDownloadAll" runat="server" 
    Text="Download All Files" 
    Enabled="false" visibe="false"
    OnClientClick="javascript:document.getElementById('modal').style.width='100%'; downloadAll();"  
    OnClick="btnGenericDownload_Click" 
    ClientIDMode="Static" 
    CssClass="buttons" />

btnGenericDownload_Click 在代码隐藏中实际上并没有做任何事情。这是被调用的 JS 函数:

function downloadAll() {
            $.ajax({
                url: 'GenerateDownloadFile.aspx?filetype=all',
                type: 'GET',
                done: function () {
                    var iframe = document.createElement("iframe");
                    iframe.src = "GenerateDownloadFile.aspx?filetype=all";
                    iframe.style.display = "none";
                    document.body.appendChild(iframe);
                },
                complete: function () {
                    clearScreen();
                }
            });
        }

function clearScreen() {
            document.getElementById("modal").style.width = "1px";
        }

我想知道是否有任何方法可以更好地同步 - 检测何时显示另存为或文件何时存在于文件夹中,我可以在代码隐藏中执行此操作,但不确定如何将其集成到 ajax 请求的动态方面。当前,当单击或更改某些表单元素时,会激活检查文件的功能...

编辑:刚刚尝试将 downloadAll() 函数更改为:

function downloadAll() {
        document.getElementById('modal').style.width = '100%';
        $.ajax({
            url: 'GenerateCNDownloadFile.aspx?filetype=all',
            type: 'GET',
            success: function () {
                var iframe = document.createElement("iframe");
                iframe.src = "GenerateCNDownloadFile.aspx?filetype=all";
                iframe.style.display = "none";
                document.body.appendChild(iframe);

            },
            done: function () {
                clearScreen();
            }
        });
    }

名为 GenerateCNDownloadFile.aspx 的文件在其代码隐藏中具有以下功能,该功能实际上将文件流式传输到浏览器并启动“另存为”对话框:

public void StreamFileToBrowser(string sfilename, byte[] fileBytes)
    {
        try
        {
            Response.Clear();
            Response.ClearHeaders();

            Response.AppendHeader("Content-disposition", String.Format("attachment; filename=\"{0}\"", System.IO.Path.GetFileName(sfilename)));
            Response.AppendHeader("Content-Type", "binary/octet-stream");
            Response.AppendHeader("Content-length", fileBytes.Length.ToString());

            Response.BinaryWrite(fileBytes);

            if (Response.IsClientConnected)
                Response.Flush();
        }
        catch (Exception ex)
        {
            ErrorLog("StreamFileToBrowser: " + ex.Message);
        }
    }

【问题讨论】:

  • 出于好奇,这如何与按钮 Enabled="false" visibe="false" 一起使用? (并且可见的拼写错误。这可能是问题吗?)
  • 您是否尝试将clearScreen() 放入done 部分?还可以看看在 ajax 调用之前将 OnClientClick 中的 js 放入 downloadAll 函数时会发生什么。
  • 这些是按钮的初始值,但在另一个选择列表选择有效选项后它们变为真。
  • @wazz,刚刚在 ajax 语句中添加了 done: 部分并将 clearScreen 移入其中,但现在发生的情况是动画永远不会消失,似乎它永远不会运行。我在 Chrome 开发工具中设置断点并运行成功项目,但它永远不会到达完成线......
  • 基本上不需要 AJAX 调用...创建 iframe,它将发送获取和检索文件。在该帧上设置轮询...(setInterval,或 setTimeout,..)

标签: javascript c# asp.net ajax webforms


【解决方案1】:

好吧,在尝试了很多不同的方法来创建 iframe 并检查它是否已加载并且没有太多内容之后,我终于遇到了类似问题的答案 (https://stackoverflow.com/a/23797348/773648),并且能够使用代码和它似乎正在工作。这是新的 downloadAll() 函数:

function downloadAll() {
        document.getElementById('modal').style.width = '100%';
        $.ajax({
            url: 'GenerateCNDownloadFile.aspx?filetype=all',
            type: 'GET',
            xhrFields: {
                responseType: 'blob' // to avoid binary data being mangled on charset conversion
            },
            success: function (blob, status, xhr) {
                // check for a filename
                var filename = "";
                var disposition = xhr.getResponseHeader('Content-Disposition');
                if (disposition && disposition.indexOf('attachment') !== -1) {
                    var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
                    var matches = filenameRegex.exec(disposition);
                    if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
                    clearScreen();
                }

                if (typeof window.navigator.msSaveBlob !== 'undefined') {
                    // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
                    window.navigator.msSaveBlob(blob, filename);
                } else {
                    var URL = window.URL || window.webkitURL;
                    var downloadUrl = URL.createObjectURL(blob);

                    if (filename) {
                        // use HTML5 a[download] attribute to specify filename
                        var a = document.createElement("a");
                        // safari doesn't support this yet
                        if (typeof a.download === 'undefined') {
                            window.location.href = downloadUrl;
                        } else {
                            a.href = downloadUrl;
                            a.download = filename;
                            document.body.appendChild(a);
                            a.click();
                        }
                    } else {
                        window.location.href = downloadUrl;
                    }

                    setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
                }
            }
        });
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 2011-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多