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).