Web service to donwload a document returns the following:
%PDF-1.5
%����
1 0 obj
<</Type/Catalog/Pages 2 0 R/Lang(en-GB) /StructTreeRoot 14 0 R/MarkInfo<</Marked true>>>>
endobj
2 0 obj
<</Type/Pages/Count 1/Kids[ 3 0 R] >>
endobj
3 0 obj
<</Type/Page/Parent 2 0 R/Resources<</Font<</F1 5 0 R/F2 8 0 R>>/ExtGState<</GS7 7 0 R>>/ProcSet[/PDF
/Text/ImageB/ImageC/ImageI] >>/MediaBox[ 0 0 595.32 841.92] /Contents 4 0 R/Group<</Type/Group/S/Transparency
/CS/DeviceRGB>>/Tabs/S/StructParents 0>>
endobj
4 0 obj
To convert this data to file, i'm using the following code:
$.ajax({
url: "/documents/docDownload",
type: "GET",
async: true,
headers: {
responseType: "arraybuffer"
},
success: function(data,status,xhr) {
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = window.URL.createObjectURL(file);
var a = document.createElement("a");
a.href = fileURL;
a.download = data.name || "newPDF2";
document.body.appendChild(a);
a.click();
$(window).on('focus', function(e) {
$('a').remove();
});
}
})
The functions returns me a pdf file, however when i open the pdf file, it's empty, seems that during the conversion was lost information.
Anybody knows why is it happening?
PHP - Web-Service code
$path = "/xxx/xxx/xxx/xxx/work.pdf";
$res = $app->response();
$res['Content-Description'] = 'File Transfer';
$res['Content-Type'] = 'application/force-download';
$res['Content-Type'] = 'application/pdf';
$res['Content-Disposition'] ='attachment; filename=' . basename($path);
$res['Content-Transfer-Encoding'] = 'binary';
$res['Expires'] = '0';
$res['Cache-Control'] = 'must-revalidate';
$res['Pragma'] = 'public';
$res['Content-Length'] = filesize($path);
readfile($path);
So, it was just as I expected. You guys just won't learn - jQuery is not a good idea for complex XHR. They have bigger tasks to do than keep implementing rarely used XHR tweaks.
The problem was that as the received data was converted to string, it was converted to UTF-8, growing in length and becoming corrupted:

We need to get a byte array, and I think that's what you were attempting with responseType: "arraybuffer". But that's not supposed to be a header. Server doesn't give a damn how you convert the received data. This is how you set it up:
var r = new XMLHttpRequest();
r.open("GET", ".../test.pdf");
// This configures how the data is parsed
r.responseType = "arraybuffer";
r.onload = function() {
var file = new Blob([this.response], {type: 'application/pdf'});
var fileURL = window.URL.createObjectURL(file);
var a = document.createElement("a");
a.href = fileURL;
a.download = "newPDF2";
document.body.appendChild(a);
a.click();
$(window).on('focus', function(e) {
$(a).remove();
});
}
r.send();
And this works. Also, if you want to set file name either parse it from url, like this:
var file_name = ".../test.pdf".match(/(^|\/)[^/]+$/)[2];
or send a proper file name header and parse it:
var file_name = this.getResponseHeader("Content-Disposition").match(/filename=(.*?)$/)[1];
However I still don't understand why don't you force download from server...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With