我有一个链接,用户点击以获得PDF。在jQuery中,我创建了一个到服务器的POST ajax调用来获取PDF。PDF来给我正确的内容标题等,通常会导致浏览器打开阅读器插件,或允许用户保存PDF。
由于我使用ajax调用来获取PDF,所以我不知道如何处理在OnSuccess回调中获得的数据。如何将接收到的数据提供给浏览器,并允许它对PDF响应执行其默认操作?
发布于 2010-02-03 02:40:01
您根本不需要jQuery。通常只需通过表单提交帖子,然后在服务器端添加HTTP标头
Content-Disposition: attachment; filename="whatever.pdf"
浏览器将执行其默认操作。
或者,如果您希望更加小心地报告在PDF生成过程中可能发生的任何错误,您可以这样做。使用jQuery将参数发布到您的服务器。在服务器上,生成二进制内容并将其缓存在某个位置几分钟,可通过放入用户会话中的键进行访问,并向页面返回“成功”Ajax响应(如果存在错误,则返回“错误”响应)。如果页面返回一个成功响应,它可以立即执行以下操作:
window.location = "/get/my/pdf";
然后,服务器返回缓存的PDF内容。请确保包含Content-Disposition标头,如上所述。
发布于 2013-02-06 05:51:35
答案中提到的"jQuery Plugin for Requesting like Ajax-like File Downloads“让我找到了正确的方向,但它并不完全适用于我的情况,因为我有一个复杂的对象和对象数组要作为我的搜索条件/过滤器数据传递。我想我应该分享我的代码,以防其他人也遇到这种情况。
$.download = function (url, data, method) {
if (url && data) {
//convert the data object into input HTML fields
var inputs = '';
var convertToInput = function (key, keyStr, obj) {
if (typeof obj === 'undefined') {
return;
} else if (typeof obj === "object") {
for (var innerKey in obj) {
if (obj.hasOwnProperty(innerKey)) {
var innerKeyStr = '';
if (keyStr === '') {
innerKeyStr = innerKey.toString();
} else {
innerKeyStr = keyStr + "[" + innerKey.toString() + "]";
}
convertToInput(innerKey, innerKeyStr, obj[innerKey]);
}
}
return;
} else if ($.isArray(obj)) {
obj.forEach(function (item) {
convertToInput(key, keyStr + "[]", item);
});
return;
}
inputs += "<input type='hidden' name='" + keyStr + "' value='" + obj + "' />";
};
convertToInput(null, '', data);
//send request
jQuery('<form action="' + url + '" method="' + (method || 'post') + '">' + inputs + '</form>').appendTo('body').submit().remove();
};
};
$.download('/api/search?format=csv', searchData, 'POST');
这可能没有多大区别,但为了提供一些上下文,我提供了一个调用WebAPI、MVC4和nHibernate的javascript和knockout UI。查询字符串的'format=csv‘部分触发MediaTypeFormatter将返回的模型转换为CSV文件类型。如果我将其关闭,那么我将从API中获得模型,并可以填充一个平滑的网格以供显示。
发布于 2014-09-17 20:22:16
我也有同样的问题,但最重要的是我使用了一个RESTFUL webservice
,并且有一个复杂的数据对象,我必须发布它。
我的解决方案是:像jQuery插件一样,我构建一个临时公式并提交它。但是我将数据对象作为参数与jQuery.param()
内容一起发送(我在这里使用AngularJS
,但它也应该与json一起工作)。
Javascript:
$('<form target="_blank" action="' + appConstants.restbaseurl + '/print/pdf" method="POST">' +
"<input name='data' value='" + angular.toJson($scope.versicherung) + "' />" +
'</form>').appendTo('body').submit().remove();
在服务器端,我们使用带有JACKSON
提供程序的CXF REST Service
:
Spring Config:
<jaxrs:server id="masterdataService" address="/">
<jaxrs:serviceBeans>
<ref bean="printRestServiceBean" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
<bean class="de.controller.ExceptionHandler" />
</jaxrs:providers>
</jaxrs:server>
在控制器中,我提取了参数并将其转换回Java Pojo:
package de.controller;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
@Path(Constants.PRINT_PATH)
@Consumes({ MediaType.APPLICATION_JSON, "application/x-www-form-urlencoded"})
@Produces("application/pdf; charset=UTF-8")
public class PrintRestController {
@Autowired
private PrintService printService;
@POST
@Produces("application/pdf")
@Path("/pdf")
public Response getPDF(@FormParam("data") String data) {
return printService.getPDF(json2Versicherung(data));
}
private Versicherung json2Versicherung(String data) {
Versicherung lVersicherung = null;
try {
ObjectMapper mapper = new ObjectMapper();
lVersicherung = mapper.readValue(data, Versicherung.class);
} catch(Exception e) {
LOGGER.error("PrintRestController.json2Versicherung() error", e);
}
return lVersicherung;
}
}
在PrintService中,我构建了pdf二进制文件和响应:
@Override
public Response getPDF(Versicherung pVersicherung) {
byte[] result = ... //build the pdf from what ever
ResponseBuilder response = Response.ok((Object) result);
response.header("Content-Disposition", "inline; filename=mypdf.pdf");
return response.build();
}
这个解决方案适用于所有浏览器(即使是IE9,它不能处理数据网址),在平板电脑和智能手机上,它与弹出窗口拦截器没有问题
https://stackoverflow.com/questions/2186562
复制相似问题