Take Binary data and save it as an .mp3 file Javascript

So I have a Node.js script and a Javascript file communicating with each other, and everything works except the Node.js is supposed to return data for an .mp3 file.

The data is binary, it looks like gibberish, how would I take that data it returns and allow the user to download it on a webpage using Javascript?

It gets data using http.responseText by the way.

Node.js Code

//initilization
var querystring = require('querystring');
var http = require('http');
var url = require('url');
var fileSystem = require('fs');
var path = require('path');
var util = require('util');

//convert function
function convert(voiceToUse, textToConvert, response)
{
    console.log("Sending Convert Request...");

    //data to send as a query
    var data = querystring.stringify(
    {
        username: 'user',
        password: 'pass',
        action: 'convert',
        voice: voiceToUse,
        text: textToConvert
    });

    //options to use
    var options = {
        host: 'ws.ispeech.org',
        port: 80,
        path: '/api/rest/1.5',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': data.length
        }
    };

    //http post request
    var req = http.request(options, function (res)
    {
        res.setEncoding('utf8');
        res.on('data', function (chunk)
        {
            console.log("Body: " + chunk);
            var fileId = chunk.substr(chunk.indexOf("fileid") + 7);
            console.log("Converting File...");
            download(fileId.substr(0, fileId.search("&")), response);

        });
    });


    req.on('error', function (e)
    {
        console.log('problem with request: ' + e.message);
    });

    req.write(data);
    req.end();
}

//download function
function download(id, response)
{

    //data to send as a query
    var data = querystring.stringify(
    {
        username: 'user',
        password: 'pass',
        action: 'download',
        fileid: id
    });

    //options to use
    var options = {
        host: 'ws.ispeech.org',
        port: 80,
        path: '/api/rest/1.5',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': data.length
        }
    };

    //http post request
    var req = http.request(options, function (res)
    {
        res.on('data', function (chunk)
        {
            if (JSON.stringify(res.headers).indexOf("audio/mp3") != -1)
            {
                console.log("Downloading Chunk...");
                /*var fs = require('fs'),
                   str = 'string to append to file';
                fs.open('test.mp3', 'a', 666, function (e, id)
                {
                    fs.write(id, chunk, 0, chunk.length, 0, function ()
                    {
                        fs.close(id, function ()
                        {
                        });
                    });
                });*/
                response.write(chunk, "binary");
            }
            else
            {
                download(id, response);
            }

        });

        res.on('end', function ()
        {   
            if (JSON.stringify(res.headers).indexOf("audio/mp3") != -1){
            response.end();
            }
        });
    });


    req.on('error', function (e)
    {
        console.log('problem with request: ' + e.message);
    });

    req.write(data);
    req.end();
}
http = require('http');
fs = require('fs');
server = http.createServer( function(req, res) {

    console.dir(req.param);

    if (req.method == 'POST') {
        console.log("POST");
        var body = '';
        req.on('data', function (data) {
            body += data;
            console.log("Partial body: " + body);
        });
        req.on('end', function () {
            console.log("Body: " + body);
            if(body){
                convert('engfemale1', body, res);
                res.writeHead(200, {
                    'Content-Type': 'audio/mp3', 
                    'Content-Disposition': 'attachment; filename="tts.mp3"'
                });
            }
        });

    }
});

port = 8080;
server.listen(port);
console.log('Listening at port ' + port);

Javascript code

console.log('begin');
        var http = new XMLHttpRequest();
        var params = "text=" + bodyText;
        http.open("POST", "http://supersecretserver:8080", true);

        http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        //http.setRequestHeader("Content-length", params.length);
        //http.setRequestHeader("Connection", "close");

        http.onreadystatechange = function() {
            console.log('onreadystatechange');
            if (http.readyState == 4 && http.status == 200) {
                alert(http.responseText);//response text is binary mp3 data
            }
            else {
                console.log('readyState=' + http.readyState + ', status: ' + http.status);
            }
        }

        console.log('sending...')
        http.send(params);
        console.log('end');

You could try using data URLs:

<a href="data:audio/mpeg3;charset=utf-8;base64,Zm9vIGJhcg==">mp3 download</a>

Not the best browser support though.

It is also possible to use data URLs directly in audio tags.


A better solution would be to save the mp3 on your server somewhere and return a link to it for a mp3 player to use.