Javascript 为什么不能使用ajax请求下载文件?

Javascript 为什么不能使用ajax请求下载文件?,javascript,ajax,post,download,Javascript,Ajax,Post,Download,在我们的应用程序中,我们需要实现以下场景: 从客户端发送请求 服务器处理请求并生成文件 服务器返回文件作为响应 客户端浏览器显示文件下载弹出对话框,允许用户下载文件 我们的应用程序是基于ajax的应用程序,因此发送ajax请求(如使用jquery.ajax()函数)将非常简单方便 但在Googiling之后,事实证明只有在使用非ajax POST请求(如中所述)时才能下载文件。因此,我们需要实现更丑陋、更复杂的解决方案,这需要使用嵌套的隐藏字段构建表单的HTML结构 有人能简单地解释一下为什么a

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

  • 从客户端发送请求
  • 服务器处理请求并生成文件
  • 服务器返回文件作为响应
  • 客户端浏览器显示文件下载弹出对话框,允许用户下载文件
  • 我们的应用程序是基于ajax的应用程序,因此发送ajax请求(如使用
    jquery.ajax()
    函数)将非常简单方便

    但在Googiling之后,事实证明只有在使用非ajax POST请求(如中所述)时才能下载文件。因此,我们需要实现更丑陋、更复杂的解决方案,这需要使用嵌套的隐藏字段构建
    表单
    的HTML结构


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

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

    这是我两天前问自己的问题。有一个项目,客户端使用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');
            },
    
    });
    

    这可以使用新的HTML5特性Blob来实现。有一个库可以用作该功能之上的包装器。

    这是由于这样一个事实,即通过AJAX检索的所有内容都进入javascript“内存”。而且您不想将文件存储在javascript内存中,因此最好的选择应该是(BalusC的回答):
    …从中检索数据,服务器异步运行,不会干扰现有页面的显示和行为。
    因此它不会干扰页面,数据将只存储在JavaScript内存空间中。可能的重复项似乎不正确,因为您可以使用Blob保存文件,例如:,这似乎不是一个安全问题,因为它不是直接交互,只是告诉浏览器从内存而不是从服务器下载文件。它与
    window.location=urlwherefilecanbedownload
    有何不同,后者以任何方式提供文件,从而允许JS绕过所有这些?