Post complex data using ajax and open returned PDF in new window
Asked Answered
L

1

1

I need to use JQuery ajax to post a complex and sensitive data object (nested objects, arrays, and Personally Identifiable Information) to my server, where a PDF is generated and returned to the client. The client browser then should open the PDF in a new window.

Because of the nature of the data the request neither can nor should be an encoded URL - it must include the data as a JSON body.

The other questions/answers on this subject did not solve the problem in my case or do not do so completely.

Lutetium answered 30/12, 2016 at 4:29 Comment(1)
L
5

Solution

  1. POST with the data in the body as JSON.
  2. Set the expected Content-Type of the response to arraybuffer (on the client and server).
  3. When the request has complete successfully, convert the response to a Blob.
  4. Create an object url to the Blob and open it in a new window.

Notes

  • JQuery ajax does not support the arraybuffer Content-Type so the base JavaScript xhr must be used (if you don't have any other options).
  • Internet Explorer has its own functionality for handling and displaying Blob's, so a special case is needed.
  • Supported browsers does not include IE9

Code

RequestPdf = function (url, data) {
    var request = new XMLHttpRequest(), file, fileURL;
    request.open("POST", url);
    request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    request.responseType = "arraybuffer";
    request.send(data);
    request.onreadystatechange = function () {
        if (request.readyState === 4 && request.status === 200) {
            file = new Blob([request.response], { type: 'application/pdf' });
            if (window.navigator && window.navigator.msSaveOrOpenBlob) { // IE
                window.navigator.msSaveOrOpenBlob(file);
            } else {
                fileURL = URL.createObjectURL(file);
                window.open(fileURL);
            }
        }
    };
};
Lutetium answered 30/12, 2016 at 4:29 Comment(4)
What is purpose of setting .responseType to "arraybuffer" where ArrayBuffer is then converted to Blob?Connubial
createObjectUrl only takes a Blob (or a File) as an input parameter. developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURLLutetium
"where a PDF is generated and returned to the client" If server reponds with content-type:application/pdf header .responseType = "blob" could be used? Does response not have content-type:application/pdf header set?Connubial
the response actually has content-type:arraybuffer set. I have not tried to set it directly to blob, though. Your suggestion might be a more direct solution to that aspect of the problem.Lutetium

© 2022 - 2024 — McMap. All rights reserved.