首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >发布到服务器、接收PDF、通过jQuery发送给用户

发布到服务器、接收PDF、通过jQuery发送给用户
EN

Stack Overflow用户
提问于 2010-02-03 02:26:31
回答 6查看 76.1K关注 0票数 47

我有一个链接,用户点击以获得PDF。在jQuery中,我创建了一个到服务器的POST ajax调用来获取PDF。PDF来给我正确的内容标题等,通常会导致浏览器打开阅读器插件,或允许用户保存PDF。

由于我使用ajax调用来获取PDF,所以我不知道如何处理在OnSuccess回调中获得的数据。如何将接收到的数据提供给浏览器,并允许它对PDF响应执行其默认操作?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 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标头,如上所述。

票数 31
EN

Stack Overflow用户

发布于 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中获得模型,并可以填充一个平滑的网格以供显示。

票数 4
EN

Stack Overflow用户

发布于 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,它不能处理数据网址),在平板电脑和智能手机上,它与弹出窗口拦截器没有问题

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2186562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档