为什么无法使用ajax请求下载文件?

IT技术 javascript ajax post download
2021-01-23 09:23:06

在我们的应用程序中,我们需要实现以下场景:

  1. 从客户端发送请求
  2. 服务器处理请求并生成文件
  3. 服务器返回文件作为响应
  4. 客户端浏览器显示文件下载弹出对话框并允许用户下载文件

我们的应用程序是基于ajax的应用程序,因此我们发送ajax请求(如使用jquery.ajax()函数)将非常容易和方便

但是经过谷歌搜索后,结果证明只有在使用非 ajax POST 请求时才可以下载文件(如这个流行的 SO 线程中所述)。所以我们需要实现更丑陋和更复杂的解决方案,需要构建form带有嵌套隐藏字段的HTML 结构

有人能简单解释一下为什么不能使用ajax请求下载文件吗?这背后的机制是什么?

4个回答

这与 AJAX 无关。当然,您可以使用 AJAX 下载文件。但是文件将保存在内存中,即您不能将文件保存到磁盘。这是因为 JavaScript 无法与磁盘交互。这将是一个严重的安全问题,并且在所有主要浏览器中都被阻止。

这似乎不正确,因为您可以使用 Blob 来保存文件,例如这里:stackoverflow.com/questions/19327749/...,这似乎不是安全问题,因为它不是直接交互,而只是告诉浏览器从内存而不是从服务器下载文件。
2021-03-17 09:23:06
它与window.location = urlWhereFileCanBeDownloaded无论如何都提供文件的 , 从而允许 JS 绕过所有这些的方法有什么不同?
2021-04-09 09:23:06

这可以使用名为 Blob 的新 HTML5 功能来完成。有一个库FileSaver.js可以用作该功能之上的包装器。

这与我两天前问自己的问题相同。有一个客户端使用 ExtJS 编写的项目,服务器端实现在 ASP.Net 上。我必须将服务器端转换为 Java。有一个下载 XML 文件的功能,该文件是在客户端发出 Ajax 请求后生成的。众所周知,Ajax 请求后无法下载文件,只能将其存储在内存中。但是...在原始应用程序浏览器中显示通常的对话框,其中包含打开、保存和取消下载选项。ASP.Net 以某种方式改变了标准行为......我需要两天时间再次证明 - 无法通过请求通常的方式下载文件......唯一的例外是 ASP.Net......这里是 ASP.Net代码

public static void WriteFileToResponse(byte[] fileData, string fileName)
    {
        var response = HttpContext.Current.Response;

        var returnFilename = Path.GetFileName(fileName);
        var headerValue = String.Format("attachment; filename={0}", 
            HttpUtility.UrlPathEncode(
                String.IsNullOrEmpty(returnFilename) 
                    ? "attachment" : returnFilename));
        response.AddHeader("content-disposition", headerValue);
        response.ContentType = "application/octet-stream";
        response.AddHeader("Pragma", "public");

        var utf8 = Encoding.UTF8;
        response.Charset = utf8.HeaderName;
        response.ContentEncoding = utf8;
        response.Flush();
        response.BinaryWrite(fileData);
        response.Flush();
        response.Close();
    }

该方法是从 WebMethod 调用的,而 WebMethod 又是从 ExtJS.Ajax.request 调用的。这就是魔法。对我来说是什么,我已经结束了 servlet 和隐藏的 iframe ......

您可以通过在下载页面中使用隐藏的 iframe 来做到这一点

只需在您的 ajax 成功响应中设置隐藏 ifame 的 src,您的任务就完成了...

  $.ajax({
        type: 'GET',
        url: './page.php',
        data: $("#myform").serialize(),
        success: function (data) {
          $("#middle").attr('src','url');
        },

});