当前位置: 首页 > 知识库问答 >
问题:

处理从ajax post下载的文件

汤嘉平
2023-03-14

我有一个javascript应用程序,它向某个URL发送ajax POST请求。响应可能是一个JSON字符串,也可能是一个文件(作为附件)。我可以很容易地在ajax调用中检测到内容类型和内容配置,但是一旦检测到响应包含文件,我如何提供客户端下载它呢?我在这里读过很多类似的文章,但没有一篇能提供我想要的答案。

请,请,请不要发布建议我不应该为此使用ajax或者我应该重定向浏览器的答案,因为这些都不是一个选项。使用纯HTML表单也不是一种选择。我需要的是向客户端显示一个下载对话框。这能不能做到,怎么做到?

共有2个答案

东门秦迟
2023-03-14

不要这么快就放弃,因为这可以(在现代浏览器中)使用FileAPI的部分完成:

var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.responseType = 'blob';
xhr.onload = function () {
    if (this.status === 200) {
        var blob = this.response;
        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, '');
        }

        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
        }
    }
};
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send($.param(params, true));

或者如果使用jQuery.ajax:

$.ajax({
    type: "POST",
    url: url,
    data: params,
    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, '');
        }

        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
        }
    }
});
督辉
2023-03-14

创建表单,使用POST方法,提交表单-不需要IFRAME。当服务器页面响应请求时,为文件的mime类型编写一个响应头,它将显示一个下载对话框--我已经做过很多次了。

你想要应用程序/下载的内容-类型-只需搜索如何为你正在使用的任何语言提供下载。

 类似资料:
  • 问题内容: 我有一个JavaScript应用程序,可将ajax POST请求发送到某个URL。响应可能是JSON字符串,也可能是文件(作为附件)。我可以在ajax调用中轻松检测Content-Type和Content- Disposition,但是一旦检测到响应中包含文件,如何为客户端提供下载文件?我在这里阅读了许多类似的主题,但是没有一个主题提供我想要的答案。 拜托,拜托,请不要发布暗示我不应该

  • 问题内容: 我想知道它有Safari Selenium Webdriver所需的任何功能或选项设置,可以将文件保存到特定位置,就像我们为firefox驱动程序所做的那样。 还想禁用文件保存对话框的弹出窗口。 问候,Himanshu 问题答案: 您可以检查以下链接。你工作吗,但不确定 http://code.google.com/p/selenium/wiki/DesiredCapabilities

  • 本文向大家介绍php文件下载处理方法分析,包括了php文件下载处理方法分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php文件下载的处理方法。分享给大家供大家参考。具体分析如下: php能够处理多种条件的文件下载,先来看下面示例: 分析上述代码: 第一行代码是强制下载; 第二行代码是给下载的内容指定一个名字; 第三行代码是把下载的内容读进文件中。   一直以为要在一个页面中同时下载多

  • 问题内容: 如何使用Java中的HttpResponse处理下载?我向特定站点发出了HttpGet请求- 该站点返回要下载的文件。如何处理此下载?InputStream似乎无法处理它(或者我使用的是错误的方法。) 问题答案: 假设您实际上在谈论HttpClient,这是一个SSCCE: 在这里工作正常。您的问题出在其他地方。

  • 我有回家的路线。在这个主路由中,我使用Jimp库来处理图像,调整它的大小,然后更改质量,最后将图像保存在目录中,但我想下载图像,以便用户可以在他的机器上下载。但它没有下载。我正确地保存在名为output.jpg的目录中。这是密码 app.get(“/”,(req,res)=>{ res.type(“jpg”);RES.Attachment(“output.jpg”) jimp.read('lenn

  • 问题内容: 所有。我使用qwebkit pyqt4来实现浏览器。我有一个简单的代码来呈现页面。我可以浏览网站,但不能下载任何内容。 需要什么来补充可从链接下载文件的代码? 问题答案: 将处理程序连接到Webview页面的downloadRequested信号,然后使用页面的networkAccessManager来处理请求。