检测何时向用户显示另存为对话框

Detecting when a save as dialog is shown to the user

我在使用 ajax 调用(通过 jQuery)将辅助文件加载到 iframe 中的 ASP.Net 网络表单应用程序时遇到问题。这些辅助文件压缩了一堆文件,然后将它们流式传输给用户。当发生这种情况时,我有一个显示加载动画的模态,但是当我将它设置为在 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);
        }
    }

好吧,在尝试了很多不同的方法来创建 iframe 并检查它是否已加载并且没有太多之后,我终于遇到了类似问题的答案 () 并且能够使用代码,它似乎正在工作。这是新的 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]*=((['"]).*?|[^;\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
                }
            }
        });
    }