Show a pdf stream in a new window

2019-01-18 04:08发布

I'm generating in a server a PDF document that I want to show then in the client. The server side looks like following:

ByteArrayOutputStream baos = generatePDF();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=file.pdf");
response.setContentLength(baos.size());
baos.writeTo(response.getOutputStream());

In the client, I have the following code to get retrieve the PDF:

$.ajax({
    type: "POST",
    url: url,
    data: {"data": JSON.stringify(myData)},
    success: function(data, textStatus, jqXHR) {
        window.open("data:application/pdf," + escape(data));
    },
    error: function(jqXHR) {
        showError("...");
    }
});

It looks well, the new window is opened, but the PDF is not shown. It always appears an empty document.

Nevertheless, if the client looks like following, it works fine:

var form = $("<form target='_blank'>").attr({
    action : myURL,
    method : "POST"
});
var input1 = $("<input type='hidden'>").attr({
    "name": "data",
    value: JSON.stringify(myData)
});

form.append(input1);
$("body").append(form);
form.submit();
form.remove();

But I can't use the second way cause I need to manage the errors, and I can't do it using form.submit().

Any idea about what's happening with the PDF?

3条回答
Deceive 欺骗
2楼-- · 2019-01-18 04:40

I couldn't do this async, but this js returns the attachment ok for me:

$('<iframe src="url"></iframe>').appendTo('body').hide();

The browser then fires a save/view popup, which is fine for my requirements; no error handling though.

I think with your server side, you might want to return it as inline e.g. response.setHeader("Content-Disposition", "inline; filename=file.pdf");

You're setting the content length OK, it could be the success code will be firing twice, the first time at the beginning of the stream and the second time at the end.

Do let us know if you got this working.

查看更多
在下西门庆
3楼-- · 2019-01-18 04:58

Try using:

dataType: "application/pdf",
success: function(data, textStatus, jqXHR) {
    window.open(escape(data), "Title", "");
},
查看更多
Anthone
4楼-- · 2019-01-18 05:02

You can get base64 string of your pdf stream and pass it to response.

And your method change

$.ajax({
    type: "POST",
    url: url,
    data: {"data": JSON.stringify(myData)},
    success: function(data, textStatus, jqXHR) {
        var pdfWin= window.open("data:application/pdf;base64, " + data, '', 'height=650,width=840');
        // some actions with this win, example print...
    },
    error: function(jqXHR) {
        showError("...");
    }
});
查看更多
登录 后发表回答