We have a listing module.
In that there is an audio element for each row.
How can I get the mp3/wav from API and then correctly bind it with src of audio element?
Here is my code:
JS
methods:{
playa(recording_file) => {
try {
const requestOptions = {
method: 'POST',
responseType: 'arraybuffer',
headers: {
'Content-Type': 'application/json',
//'Authorization': 'Bearer ' + localStorage.getItem('jwt')
},
};
const response = axios.post(`api/playrecfile?rec=${recording_file}`)
const mp3 = new Blob([response.data], { type: 'audio/mp3' })
const url = URL.createObjectURL(mp3);//tried window.
return url;
} catch (e) {
console.log('play audio error: ', e)
}
}
}
HTML(cell of a row)(I can see data and checked value of meta also)
<div :class="classes" #click="click(data)" v-else-if="name=='Play'" title='Play'>
<!-- <span><i class="fa fa-play"></i></span> -->
<audio controls :ref="'audio'+data.recording_file" v-if="meta.is_admin==1 && data.recording_filename" :src="playa(data.recording_filename)">
</audio>
<span v-else #click="givealert()">
<i class="fa fa-play"></i>
</span>
</div>
PHP/Laravel
$out = isset($request->out) ? $request->out : "mp3";
header("Content-type: audio/x-$out");
header("Content-disposition: attachment; filename=tuzbd.$out");
header("Access-Control-Allow-Origin: *");
$file = base_path(). "/storage/app/recs/2019/05/03/tuzbd.mp3";
header("Content-length: " . filesize($file));
readfile($file);
return;
I don't use the Vue-JS framework but the logic in regular HTML5 would be:
(1) Give the audio tag an ID (eg: myAudio).
<audio id="myAudio" controls :ref="'audio'+data.recording_file" v-if="meta.is_admin==1 && data.recording_filename" :src="playa(data.recording_filename)">
</audio>
(2) Then directly update the audio tag's source with result of createObjectURL:
Using Vue-JS you want to achieve something like this:
methods:{
playa(recording_file) => {
try
{
const requestOptions = {
method: 'POST',
responseType: 'arraybuffer',
headers: {
'Content-Type': 'application/json',
//'Authorization': 'Bearer ' + localStorage.getItem('jwt')
},
};
var response = axios.post(`api/playrecfile?rec=${recording_file}`)
//# try reading into Blob as BINARY data (eg: raw bytes)
//const mp3 = new Blob([response.data], { type: 'audio/mp3' })
var mp3 = new Blob([response.data], { type: 'application/octet-stream' })
//const = URL.createObjectURL(mp3);//tried window.
//return url; //# don't Return but instead just update the audio tag's source...
//# update file path for Audio tag...
var url = (window.URL || window.webkitURL).createObjectURL( mp3 );
var audioObj = document.getElementById("myAudio");
audioObj.setAttribute("src", url); //# updates the source of the Audio tag
//# If you need to handle MP3 bytes... eg: read/modify/delete some ID3 metadata bytes...
var reader = new FileReader();
reader.readAsDataURL( mp3 );
reader.onloadend = function(evt)
{
if (evt.target.readyState == FileReader.DONE)
{
//# access MP3 bytes here... as arraybuffer
bytes_mp3 = new Uint8Array( evt.target.result ); //define your "var bytes_mp3" globally (var is outside of any function)
}
}
}
catch (e) { console.log('play audio error: ', e) }
}
Where the above FileReader reads the file as a stream of bytes (since audio tag is expecting a file, meaning its just a stream of bytes regardless if data is MP3 or PDF).
Related
I have a web app getting some audio recording input from the user.
And there is a button to save it locally as an audio file.
The resulting file I am getting is of ogg-opus format. Concretely when I use the file command I get this in the terminal:
MyMac$ file Clip.wav
Clip.wav: Ogg data, Opus audio,
MyMac$
I can check that the recording is all right using VLC.
On the other hand I can't play the file with afplay as is normally possible with an mp3, m4a or wav file.
MyMac$ afplay Clip.wav
Error: AudioFileOpen failed ('typ?')
MyMac$
Here follows my relevant code:
if (navigator.mediaDevices.getUserMedia) {
// getUserMedia is supported.
const constraints = { audio: true };
let chunks = [];
let onSuccess = function(stream) {
const mediaRecorder = new MediaRecorder(stream);
visualize(stream);
........
mediaRecorder.onstop = function(e) {
........
audio.setAttribute('controls', '');
........
audio.controls = true;
const blob = new Blob(chunks, { 'type' : 'audio/wav;codecs=0' });
chunks = [];
........
upload.addEventListener("click",
function(event) {loadToServer(blob)})
........
}
mediaRecorder.ondataavailable = function(e) {
chunks.push(e.data);
}
}
let onError = function(err) {
console.log('The following error occured: ' + err);
}
navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);
} else {
console.log('getUserMedia not supported on your browser!');
}
I would like to know how to change my code in order to generate a proper wav file or even mp3.
Note:
I have made trials modifying this line of code:
const blob = new Blob(chunks, { 'type' : 'audio/wav;codecs=0' });
in various ways, but is has no effect at all.
In order to specify the mimeType of your recording you need to tell the MediaRecorder which mimeType you prefer before it starts the recording.
- const mediaRecorder = new MediaRecorder(stream);
+ const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/wav' });
Unfortunately audio/wav is not supported by any browser. You will get an error when trying the snippet above.
Since I needed wav recordings as well I built a library which is meant to add this functionality. It's called extendable-media-recorder because it could be extended with any other (audio) codec you like.
If you don't want to use a third party library and keep the browser using the codec it likes best you can save your file like this in order to get a valid file with the correct suffix.
- const blob = new Blob(chunks, { 'type' : 'audio/wav;codecs=0' });
+ const blob = new Blob(chunks, { 'type' : mediaRecorder.mimeType });
The suffix would then be the portion of the type after the slash and before a possible semicolon.
Here is an example of a full HTML document that uses jspm to load extendable-media-recorder without a bundler.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<button id="start" disabled>start</button>
<button id="stop" disabled>stop</button>
<script type="module">
import { MediaRecorder, register } from 'https://jspm.dev/extendable-media-recorder';
import { connect } from 'https://jspm.dev/extendable-media-recorder-wav-encoder';
const $start = document.getElementById('start');
const $stop = document.getElementById('stop');
await register(await connect());
const chunks = [];
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const mediaRecoder = new MediaRecorder(stream, { mimeType: 'audio/wav' });
mediaRecoder.addEventListener('dataavailable', ({ data }) => {
chunks.push(data);
});
mediaRecoder.addEventListener('stop', ({ data }) => {
const blob = new Blob(chunks, { type : mediaRecoder.mimeType });
console.log(blob);
});
$start.addEventListener('click', () => {
mediaRecoder.start();
$stop.addEventListener('click', () => {
$stop.disabled = true;
mediaRecoder.stop();
});
$start.disabled = true;
$stop.disabled = false;
});
$start.disabled = false;
</script>
</body>
</html>
I am currently using this code to select a video file from local disk (via webpage using ) and send that to my api:
<form enctype="multipart/form-data">
<input name="file" type="file" accept="video/*"/>
<input type="button" value="Upload" />
</form>
<progress></progress>
<script language="javascript" type="text/javascript">
$(document).ready(function(){
$(':file').on('change', function () {
var file = this.files[0];
if (file.type !== "video/mp4" && file.type!== "video/quicktime") {
alert("Content must be video .mp4 or .mov")
}
$(':button').on('click', function () {
if (file.type == "video/mp4" || file.type == "video/quicktime"){
$.ajax({
// Your server script to process the upload
url: 'azureAPI',
type: 'POST',
// Form data
data: new FormData($('form')[0]),
// Tell jQuery not to process data or worry about content-type
// You *must* include these options!
cache: false,
contentType: false,
processData: false,
// Custom XMLHttpRequest
xhr: function () {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
// For handling the progress of the upload
myXhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
$('progress').attr({
value: e.loaded,
max: e.total,
});
}
}, false);
}
return myXhr;
}
});
} else {
alert ("File type must be .mp4 or .mov")
}
});
});
});
</script>
This sends (what I am assuming is) binary data in the form of this:
���
1!QAa"q2B���R�#3br��u�����S6C$%��5�cts�T&D4��U��d���e!1AQa2"q�#����3��B���X"��?��!=��W�u�ٗ�-2���?����ۯ�Կ�i���t����M���Y�-��-Vdϊ�P�<�<U#TY]K��dW
���
I believe this includes webkitform boundary etc.
I am now trying to save that binary data to a block blob, however I am having trouble saving binary data to Azure block blob using:
var buf = Buffer.from(req.body, 'binary');
blobService.createBlockBlobFromText(container, 'fileName.mp4', buf, {contentSettings: {contentType: 'video/mp4', contentEncoding: 'binary'}}, function (error, result, response) {
if(!error){
callback('uploaded');
} else {
callback('nope');
}
});
I have also tried to create a readable stream:
var container = 'abc';
var azure = require('azure-storage');
const getStream = require('into-stream');
var blobService = azure.createBlobService();
module.exports = function (context, req) {
var json = req.body;
save (context, json, function(result){
context.log(result);
context.done();
})
}
function save (context, json, callback){
var buf = Buffer.from(json);
var stream = getStream(buf);
var streamLength = buf.length;
blobService.createBlockBlobFromStream(container, 'fileName.mp4', stream, streamLength, {contentSettings: {contentType: 'video/mp4'}}, function (error, result, response) {
if(!error) {
callback('uploaded');
} else {
callback('nope');
}
});
}
I tried this, without the contentSettings at first but that saved the data as contentType: application/octet-stream which wasn't opening as a video. I then added contentType, and lastly tried adding contentEncoding as well.
This saved the correct contentType but still the video could not be opened.
Does anyone know how to save binary data to Azure blob storage via this method? It seems to save the file, but when trying to open it, it is corrupted/not encoded correctly? I am unsure of the issue. Perhaps I need to remove the webkitform boundary etc data from it before saving?
Thanks for any pointers, apologies if I left anything out.
i need to play sound with user click on the preview icon .
this is my html code :
<audio controls>
<source [src]="fileSource" type="audio/mp3">
</audio>
this this is ts code :
fileSource: any;
ngOnInit(): void {
if (typeof this.data.src === 'number') {
this.getImageFromService();
}
}
createImageFromBlob(image: Blob): void {
const reader = new FileReader();
reader.addEventListener('load', () => {
this.fileSource = reader.result;
}, false);
if (image) {
reader.readAsDataURL(image);
}
}
getImageFromService(): void {
this.isLoading = true;
this.postFileService.downloadFile(this.data.src).subscribe(data => {
this.createImageFromBlob(data);
this.isLoading = false;
}, error => {
this.isLoading = false;
console.log(error);
});
}
and this is my service :
downloadFile(id: number): Observable<Blob> {
const URL = `${this.appConfig.apiEndpoint + '/PostFileContent/DownloadFile/' + id}`;
return this.http.get(URL, { responseType: 'blob' });
}
now my prolem is this :
i need to when click the preview icon T open the modal dialog box and play audio .
when i click on the preview icon the file is downloaded but it not play .
whats the problem ? how can i solve this ???
Following code will work for playing audio automatically file which was retrieved from backend(node.js).
angular.html
<audio controls>
<source type="audio/mpeg" [src]="fileSource" >
</audio>
angualr.ts
// mention your backend url directly here like below
fileSource:any = 'http://localhost:1234/getAudioFile';
node-backend-code
app.use('/getAudioFile',function(req,res,next){
// i stored sample mp3 file in my local directory
var filePath = path1.join(__dirname, './sample.mp3');
var stat = fileSystem.statSync(filePath);
res.writeHead(200, {
'Content-Type': 'audio/mpeg',
'Content-Length': stat.size
});
var readStream = fileSystem.createReadStream(filePath);
// We replaced all the event handlers with a simple call to readStream.pipe()
readStream.pipe(res);
// res.send("this is audio ");
next();
});
Note:: Make sure that you get directly audio file from backend(irrespective of node or java).
I have created a voice recorder in HTML.
first, it will request stream, after allowing request stream it will show two buttons, like "start" and "Stop". After recording it will convert blob URL to base64 data.
Now what I want is, I have a table SQLserver I want to store base64 data in that table. I am creating this web page using ASP .NET MVC. The base64 data is in javascript. I don't know how to connect to the server.
Please help me.
Thanks.
Html Page code:
<body>
<h1> Audio Recorder</h1>
<p> For now it is supported only in Firefox(v25+) and Chrome(v47+)</p>
<div id='gUMArea'>
<div>
Record:
</div>
<button class="btn btn-default mediaAudio" id='gUMbtn'>Request Stream</button>
</div>
<div id='btns'>
<button class="btn btn-default" id='start'>Start</button>
<button class="btn btn-default" id='stop'>Stop</button>
</div>
<div>
<ul class="list-unstyled" id='ul'></ul>
</div>
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="~/script.js"></script>
</body>
JavaScript Code:
'use strict'
let log = console.log.bind(console),
id = val => document.getElementById(val),
ul = id('ul'),
gUMbtn = id('gUMbtn'),
start = id('start'),
stop = id('stop'),
stream,
recorder,
counter=1,
chunks,
media;
gUMbtn.onclick = e => {
let mv = id('.mediaAudio'),
mediaOptions = {
audio: {
tag: 'audio',
type: 'audio/mpeg',
ext: '.mp3',
gUM: {audio: true}
}
};
media = mediaOptions.audio;
navigator.mediaDevices.getUserMedia(media.gUM).then(_stream => {
stream = _stream;
id('btns').style.display = 'inherit';
start.removeAttribute('disabled');
recorder = new MediaRecorder(stream);
recorder.ondataavailable = e => {
chunks.push(e.data);
if (recorder.state == 'inactive') saveLink()
};
log('got media successfully');
}).catch(log);
}
start.onclick = e => {
start.disabled = true;
stop.removeAttribute('disabled');
chunks=[];
recorder.start();
}
stop.onclick = e => {
stop.disabled = true;
recorder.stop();
start.removeAttribute('disabled');
}
function saveLink() {
let blob = new Blob(chunks, { type: media.type })
;
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
var base64data = reader.result;
console.log(base64data.substr(base64data.indexOf(',') + 1));
alert(base64data.substr(base64data.indexOf(',') + 1));
}
}
Now it have base64 data in base64data variable, I want to store this variable sql server.
Regards.
Your solution has 2 parts:
Getting a blob out of the blob url
Sending that blob to the server
For first part you can use "Fake ajax" technique just pass blob url (url of download.ogg) as the url of your ajax
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200){
var result = this.response
}
}
xhr.open('GET', 'blob:http://example.com/bbdaabf8-ddf2-40d3-975d-ade742417c71');
xhr.responseType = 'blob';
xhr.send();
After ajax completes result will hold a blob now you just send it to ther server using this answer
I have been working on this problem for the last few days. With no luck on trying to display the stream on <embed src> tag, I just tried to display it on a new window.
The new window shows PDF controls only )
Any idea why the content of the pdf is not showing?
CODE:
$http.post('/fetchBlobURL',{myParams}).success(function (data) {
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
});
You need to set the responseType to arraybuffer if you would like to create a blob from your response data:
$http.post('/fetchBlobURL',{myParams}, {responseType: 'arraybuffer'})
.success(function (data) {
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
});
more information: Sending_and_Receiving_Binary_Data
If you set { responseType: 'blob' }, no need to create Blob on your own. You can simply create url based with response content:
$http({
url: "...",
method: "POST",
responseType: "blob"
}).then(function(response) {
var fileURL = URL.createObjectURL(response.data);
window.open(fileURL);
});
I use AngularJS v1.3.4
HTML:
<button ng-click="downloadPdf()" class="btn btn-primary">download PDF</button>
JS controller:
'use strict';
angular.module('xxxxxxxxApp')
.controller('MathController', function ($scope, MathServicePDF) {
$scope.downloadPdf = function () {
var fileName = "test.pdf";
var a = document.createElement("a");
document.body.appendChild(a);
MathServicePDF.downloadPdf().then(function (result) {
var file = new Blob([result.data], {type: 'application/pdf'});
var fileURL = window.URL.createObjectURL(file);
a.href = fileURL;
a.download = fileName;
a.click();
});
};
});
JS services:
angular.module('xxxxxxxxApp')
.factory('MathServicePDF', function ($http) {
return {
downloadPdf: function () {
return $http.get('api/downloadPDF', { responseType: 'arraybuffer' }).then(function (response) {
return response;
});
}
};
});
Java REST Web Services - Spring MVC:
#RequestMapping(value = "/downloadPDF", method = RequestMethod.GET, produces = "application/pdf")
public ResponseEntity<byte[]> getPDF() {
FileInputStream fileStream;
try {
fileStream = new FileInputStream(new File("C:\\xxxxx\\xxxxxx\\test.pdf"));
byte[] contents = IOUtils.toByteArray(fileStream);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));
String filename = "test.pdf";
headers.setContentDispositionFormData(filename, filename);
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
return response;
} catch (FileNotFoundException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
return null;
}
// I used this code with the fpdf library.
// Este código lo usé con la libreria fpdf.
var datas = json1;
var xhr = new XMLHttpRequest();
xhr.open("POST", "carpeta/archivo.php");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status === 200) {
var blob = new Blob([xhr.response], {type: 'application/pdf'});
const url = window.URL.createObjectURL(blob);
window.open(url,"_blank");
setTimeout(function () {
// For Firefox it is necessary to delay revoking the ObjectURL
window.URL.revokeObjectURL(datas)
, 100
})
}
};
xhr.send("men="+datas);
You are not required to set the response type if your data is a byte array, make sure you convert it to Uint8Array before passing it to blob.
Example:
let byteArray = new Uint8Array(data)
let file = new Blob(
[byteArray],
{type: 'application/pdf'}
)
It works for me.
If your data is not byteArray, make sure to convert it to byteArray and follow above-mentioned steps to make it work.
//For example if your data is base-64 encoded string.
let byteChars = atob(data); //To decrypt data
let dataArray = = new Array(byteChars.length);
for(let i=0; i< byteChars.length; i++){
dataArray[i] = byteChars.charCodeAt(i);
}
let byteArray = new Uint8Array(dataArray)
let file = new Blob(
[byteArray],
{type: 'application/pdf'}
)
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.
I have been struggling for days finally the solution which worked for me is given below. I had to make the window.print() for PDF in new window needs to work.
var xhr = new XMLHttpRequest();
xhr.open('GET', pdfUrl, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this['status'] == 200) {
var blob = new Blob([this['response']], {type: 'application/pdf'});
var url = URL.createObjectURL(blob);
var printWindow = window.open(url, '', 'width=800,height=500');
printWindow.print()
}
};
xhr.send();
Some notes on loading PDF & printing in a new window.
Loading pdf in a new window via an iframe will work, but the print will not work if url is an external url.
Browser pop ups must be allowed, then only it will work.
If you try to load iframe from external url and try window.print() you will get empty print or elements which excludes iframe. But you can trigger print manually, which will work.
problem is, it is not converted to proper format. Use function "printPreview(binaryPDFData)" to get print preview dialog of binary pdf data.
you can comment script part if you don't want print dialog open.
printPreview = (data, type = 'application/pdf') => {
let blob = null;
blob = this.b64toBlob(data, type);
const blobURL = URL.createObjectURL(blob);
const theWindow = window.open(blobURL);
const theDoc = theWindow.document;
const theScript = document.createElement('script');
function injectThis() {
window.print();
}
theScript.innerHTML = `window.onload = ${injectThis.toString()};`;
theDoc.body.appendChild(theScript);
};
b64toBlob = (content, contentType) => {
contentType = contentType || '';
const sliceSize = 512;
// method which converts base64 to binary
const byteCharacters = window.atob(content);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {
type: contentType
}); // statement which creates the blob
return blob;
};
I ended up just downloading my pdf using below code
function downloadPdfDocument(fileName){
var req = new XMLHttpRequest();
req.open("POST", "/pdf/" + fileName, true);
req.responseType = "blob";
fileName += "_" + new Date() + ".pdf";
req.onload = function (event) {
var blob = req.response;
//for IE
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
}
};
req.send();
}
Note: this.file should be you base64 file