I know this is old but since this pointed me in the right direction, I thought I would share what I am doing in case someone else lands here. I am not using Angular btw.
The user can view or download the file. The choice is given with 2 buttons or 2 links
<button type="button" class="btn btn-primary btn-sm show_tooltip download-form" title="Download File" data-formid="{{ @your-id }}" data-forcedownload="1">
<i class="fas fa-file-download"></i>
</button>
<button type="button" class="btn btn-primary btn-sm show_tooltip download-form" title="View File" data-formid="{{ @your-id }}" data-forcedownload="0">
<i class="fas fa-search"></i>
</button>
I am using jQuery with the native plugin for xhr2. This handles the link/buttons
$('.download-form').click(function(event) {
event.preventDefault();
let fid = $(this).data('formid');
let force_download = $(this).data('forcedownload');
$.ajax({
url: '/download',
dataType: 'native',
type: 'POST',
xhrFields: {
responseType: 'blob'
},
data: {
//you can send any parameters via POST here
personID: "{{ @personID }}",
file_record_id: pfid,
file_type: "contract_form",
dept: "your-dept",
file_category: "fcategory",
force_download: force_download
},
success: function(blob, status, xhr){
if (xhr.getResponseHeader('Custom-FileError')>1) {
alertify.error(xhr.getResponseHeader('Custom-ErrorMsg'));
}else{
//I thought this would work when viewing the PDF but it does not.
blob.name = xhr.getResponseHeader('Custom-FileName');
var fileURL = URL.createObjectURL(blob);
if (xhr.getResponseHeader('Custom-ForceDownload')==1) {
window.open(fileURL);
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download=xhr.getResponseHeader('Custom-FileName');
link.click();
}else{
file_modal(fileURL,'Any Title');
}
}
}
})
});
Then, some more javascript for the modal
function file_modal(blob,the_title)
{
let spinner = "<div class='text-center'><i class='fa fa-spinner fa-spin fa-5x fa-fw'></i></div>";
$("#modal_static_label").html('Loading');
$("#modal_static .modal-body").html(spinner);
if (blob.length > 1) {
$("#modal_static").modal("show");
$("#modal_static_label").html(the_title);
$("#modal_static .modal-body").empty().append('<iframe src='+blob+' width="100%" height="500px" style="border:none;"></iframe>');
}else{
$("#modal_static .modal-body").empty().html('File error');
}
$("#modal_static .modal-footer").html('<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>');
}
On the server side you will need to send custom headers like this [PHP]
header("Content-length: $file_size");
header("Custom-FileError: 0");
header("Custom-FileName: ".$this->params['original_filename']);
header("Custom-ForceDownload: ".$this->params['force_download']);
header('Content-Type: '.$web->mime($this->full_path.$this->new_file_name));
readfile($this->full_path.$this->new_file_name);
If the user clicks "view", a modal will display the PDF if they click "download", the download window will show up with the filename of your choosing. I have tested this with PDF files less than 10mb and it works as expected.
I hope someone finds this useful.
$window
(with a dollar sign). – Footpoundsecond