我有一个基于jquery的单页web应用程序。它通过AJAX调用与基于rest的web服务通信。
我正在努力实现以下目标:
我有1 &2工作现在,和客户端jquery应用程序通过创建基于JSON数据的DOM元素在网页中显示返回的数据。我还让#3从web服务的角度工作,这意味着如果给定正确的JSON参数,它将创建并返回二进制文件。但我不确定在客户端javascript代码中处理#3的最佳方法。
是否有可能从这样的ajax调用中获得一个可下载的文件?如何让浏览器下载并保存文件?
$.ajax({
type: "POST",
url: "/services/test",
contentType: "application/json",
data: JSON.stringify({category: 42, sort: 3, type: "pdf"}),
dataType: "json",
success: function(json, status){
if (status != "success") {
log("Error loading data");
return;
}
log("Data loaded!");
},
error: function(result, status, err) {
log("Error loading data");
return;
}
});
服务器响应以下报头:
Content-Disposition:attachment; filename=export-1282022272283.pdf
Content-Length:5120
Content-Type:application/pdf
Server:Jetty(6.1.11)
另一种想法是生成PDF并将其存储在服务器上,然后返回包含文件URL的JSON。然后,在ajax成功处理程序中发出另一个调用,执行如下操作:
success: function(json,status) {
window.location.href = json.url;
}
但这样做意味着我需要对服务器进行多次调用,我的服务器需要构建可下载的文件,将它们存储在某个地方,然后定期清理存储区域。
一定有更简单的方法。想法吗?
编辑:在检查文档$。ajax,我看到响应dataType只能是xml, html, script, json, jsonp, text
之一,所以我猜没有办法直接下载一个文件使用ajax请求,除非我嵌入二进制文件使用数据URI方案建议在@VinayC答案(这不是我想做的事情)。
所以我想我的选择是:
不使用ajax,而是提交一个表单post和嵌入我的JSON数据到表单值。可能需要与隐藏的iframes等混乱。
不使用ajax,而是将我的JSON数据转换为一个查询字符串来构建一个标准的GET请求,并将window.location.href设置为这个URL。可能需要在我的点击处理程序中使用event.preventDefault()来防止浏览器从应用程序URL更改。
使用我上面的另一个想法,但从@naikus的回答中得到了建议。提交带有一些参数的AJAX请求,让web-service知道这个请求是通过AJAX调用调用的。如果web服务是从ajax调用调用的,那么只需向生成的资源返回带有URL的JSON。如果直接调用资源,则返回实际的二进制文件。
我越想越喜欢最后一个选项。通过这种方式,我可以获得关于请求的信息(生成时间、文件大小、错误消息等),并且可以在开始下载之前对这些信息采取行动。缺点是服务器上需要额外的文件管理。
还有其他方法吗?我应该知道这些方法的优缺点吗?