When utilizing jsreport, the typical approach involves using the jsreport browser SDK to efficiently manage the report results and display them in the browser. However, in your scenario where a custom URL is used on the server to render reports, the jsreport browser SDK becomes inadequate. Instead, you are required to handle the report request and response using either jQuery ajax or plain XMLHttpRequest.
Dealing with blob/binary data poses challenges when using jQuery.ajax. You would need to implement a data transport method for $.ajax to facilitate binary data handling.
/**
*
* jquery.binarytransport.js
*
* @description. jQuery ajax transport designed for making binary data type requests.
* @version 1.0
* @author Henry Algus <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a7cfc2c9d5dec6cbc0d2d4e7c0cac6cecb89c4c8ca">[email protected]</a>>
*
*/
// utilize this transport for "binary" data type
$.ajaxTransport("+binary", function(options, originalOptions, jqXHR){
// validate conditions and support for blob / arraybuffer response type
if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob))))
{
return {
// create new XMLHttpRequest
send: function(headers, callback){
// initialize variables
var xhr = new XMLHttpRequest(),
url = options.url,
type = options.type,
async = options.async || true,
// specify blob or arraybuffer. Default is blob
dataType = options.responseType || "blob",
data = options.data || null,
username = options.username || null,
password = options.password || null;
xhr.addEventListener('load', function(){
var data = {};
data[options.dataType] = xhr.response;
// execute callback and transmit data
callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
});
xhr.open(type, url, async, username, password);
// configure custom headers
for (var i in headers ) {
xhr.setRequestHeader(i, headers[i] );
}
xhr.responseType = dataType;
xhr.send(data);
},
abort: function(){
jqXHR.abort();
}
};
}
});
However, I lean towards utilizing XMLHttpRequest directly when managing blob data in a request/response as it provides more flexibility for manipulating responses.
function sendReportRequest (dataObj, cb) {
var xhr = new XMLHttpRequest()
var data = JSON.stringify(dataObj)
xhr.open('POST', 'http://url-of-your-server/' + '/Reporting/GetLossSummary', true)
xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8')
xhr.responseType = 'arraybuffer'
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
var response = xhr.response
var contentType = xhr.getResponseHeader('Content-Type')
var dataView = new DataView(response)
var blob
try {
blob = new Blob([dataView], { type: contentType })
cb(null, blob)
} catch (e) {
if (e.name === 'InvalidStateError') {
var byteArray = new Uint8Array(response)
blob = new Blob([byteArray.buffer], { type: contentType })
cb(null, blob)
} else {
cb(new Error('Can not parse buffer response'))
}
}
} else {
var error = new Error('request failed')
error.status = xhr.status
error.statusText = xhr.statusText
cb(error)
}
}
xhr.onerror = function () {
var error = new Error('request failed')
error.status = xhr.status
error.statusText = xhr.statusText
cb(error)
}
xhr.send(data)
}
sendReportRequest(dataObj, function (err, reportBlob) {
if (err) {
return console.error(err)
}
var reportFileUrl = URL.createObjectURL(reportBlob)
window.open(reportFileUrl)
})
By implementing this code snippet, you should be able to seamlessly request a PDF file and readily display it in a new browser window.