Javascript 为什么无法使用ajax请求下载文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14682556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why threre is no way to download file using ajax request?
提问by Piotr Sobczyk
In our application we need to implement following scenario:
在我们的应用程序中,我们需要实现以下场景:
- A request is send from client
- Server handles the request and generates file
- Server returns file in response
- Client browser displays file download popup dialog and allows user to download the file
- 从客户端发送请求
- 服务器处理请求并生成文件
- 服务器返回文件作为响应
- 客户端浏览器显示文件下载弹出对话框并允许用户下载文件
Our application is ajax based application, so it would be very easy and convenient for us to send ajax request (like using jquery.ajax()function).
我们的应用程序是基于ajax的应用程序,因此我们发送ajax请求(如使用jquery.ajax()函数)将非常容易和方便。
But after googilng, it turned out that file downloading is possible only when using non-ajax POST request (like described in this popular SO thread). So we needed to implement uglier and more complex solution that required building HTML structure of formwith nested hidden fields.
但是经过谷歌搜索后,结果证明只有在使用非 ajax POST 请求时才可以下载文件(如这个流行的 SO 线程中所述)。所以我们需要实现更丑陋和更复杂的解决方案,需要构建form带有嵌套隐藏字段的HTML 结构。
Could someone explain in simple words why is that ajax requests cannot be used to download file? What's the mechanics behind that?
有人能简单解释一下为什么不能使用ajax请求下载文件吗?这背后的机制是什么?
回答by freakish
It's not about AJAX. You can download a file with AJAX, of course. However the file will be kept in memory, i.e. you cannot save file to disk. This is because JavaScript cannot interact with disk. That would be a serious security issue and it is blocked in all major browsers.
这与 AJAX 无关。当然,您可以使用 AJAX 下载文件。但是文件将保存在内存中,即您不能将文件保存到磁盘。这是因为 JavaScript 无法与磁盘交互。这将是一个严重的安全问题,并且在所有主要浏览器中都被阻止。
回答by Ilya Chernomordik
This can be done using the new HTML5 feature called Blob. There is a library FileSaver.jsthat can be utilized as a wrapper on top of that feature.
这可以使用名为 Blob 的新 HTML5 功能来完成。有一个库FileSaver.js可以用作该功能之上的包装器。
回答by bes67
That's the same question I'd asked myself two days ago. There was a project with client written using ExtJS and server side realisation was on ASP.Net. I have to translate server side to Java. There was a function to download an XML file, that server generates after Ajax request from the client. We all know, that it's impossible to download file after Ajax request, just to store it in memory. But ... in the original application browser shows usual dialog with options open, save and cancel downloading. ASP.Net somehow changed the standard behaviour... It takes me two day to to prove again - there is no way to download file by request usual way ... the only exception is ASP.Net... Here is ASP.Net code
这与我两天前问自己的问题相同。有一个使用 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();
}
This method was called from WebMethod, that, in turn, was called from ExtJS.Ajax.request. That's the magic. What's to me, I've ended with servlet and hidden iframe...
该方法是从 WebMethod 调用的,而 WebMethod 又是从 ExtJS.Ajax.request 调用的。这就是魔法。对我来说是什么,我已经结束了 servlet 和隐藏的 iframe ......
回答by Naimish B. Makwana
you can do this by using hidden iframe in your download page
您可以通过在下载页面中使用隐藏的 iframe 来做到这一点
just set the src of the hidden ifame in your ajax success responce and your task is done...
只需在您的 ajax 成功响应中设置隐藏 ifame 的 src,您的任务就完成了...
$.ajax({
type: 'GET',
url: './page.php',
data: $("#myform").serialize(),
success: function (data) {
$("#middle").attr('src','url');
},
});

