我有一个Web API,它正在返回JSreport作为编码字节数组。无论我如何尝试阅读字节数组,我都会收到一个黑屏幕,或者说"未能下载pdf"的错误消息。如果我创建一个隐藏的锚标签并下载PDF,则可以正常工作。但是,我不希望用户下载它,我希望他们可以从浏览器中查看它。
Web API调用
var data = LossReportService.GetLossSummary(request);
var pdf_bytes = LossReportService.GeneratePDFUsingJSReport(data);
byte[] myBinary = new byte[pdf_bytes.Length];
pdf_bytes.Read(myBinary, 0, (int)pdf_bytes.Length);
string base64EncodedPDF = System.Convert.ToBase64String(myBinary);
var response = Request.CreateResponse(HttpStatusCode.OK, base64EncodedPDF);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
response.Content.Headers.ContentLength = pdf_bytes.Length;
return response;
javascript
$.ajax({
type: "POST",
url: "/Reporting/GetLossSummary",
data: { dataObj },
},
success: function (data) {
if (data != null) {
//I have tried this
var file = new Blob([data], { type: 'application/pdf;base64' });
var fileURL = URL.createObjectURL(file);
window.open(fileURL, "LossSummaryReport");
//which gives me a "failed to load pdf document" error
//and I have tried this, which just renders a blank page
window.open("data:application/pdf," + encodeURI(data));
}
}
});
任何建议都将不胜感激。
由于您使用的是JSReport,因此,在正常情况下,您可以使用JSReport浏览器SDK更好地使用报告结果,并在浏览器中轻松显示。但是,就您而言,您正在使用服务器中的自定义URL渲染报告,因此在这种情况下,JSReport浏览器SDK无法帮助您。相反,您需要使用jQuery Ajax或普通XMLHTTPRequest的报告请求和响应。
使用jquery.ajax很难使用blob/二进制数据,您需要将数据传输添加到$ .ajax才能处理二进制数据
/**
*
* jquery.binarytransport.js
*
* @description. jQuery ajax transport for making binary data type requests.
* @version 1.0
* @author Henry Algus <henryalgus@gmail.com>
*
*/
// use this transport for "binary" data type
$.ajaxTransport("+binary", function(options, originalOptions, jqXHR){
// check for 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){
// setup all variables
var xhr = new XMLHttpRequest(),
url = options.url,
type = options.type,
async = options.async || true,
// 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;
// make callback and send data
callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
});
xhr.open(type, url, async, username, password);
// setup custom headers
for (var i in headers ) {
xhr.setRequestHeader(i, headers[i] );
}
xhr.responseType = dataType;
xhr.send(data);
},
abort: function(){
jqXHR.abort();
}
};
}
});
但是,当在请求/响应中处理blob数据时,我更喜欢直接使用XHTMLRequest进行此操作,因为它让我以任何方式操纵响应。
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)
})
使用此代码,您应该能够请求PDF文件并在新窗口中的浏览器中显示