I am trying to download a PDF file using NodeJS then send its data to client to be embedded in the page. Here is how I download the PDF file:
exports.sendPdf = function(req, responce) {
var donneRecu = req.body;
var url = 'http://www.ieee.org/documents/ieeecopyrightform.pdf'//pdf link
http.get(url, function(res) {
var data = '';
res.on('data', function(chunk) {
console.log('downloading');
data += chunk;
});
res.on("end", function() {
console.log('downloaded');
responce.header("Access-Control-Allow-Origin", "*");
responce.header("Access-Control-Allow-Headers", "X-Requested-With");
responce.header(200, {'content-type' : 'application/pdf'});
responce.send(data);
});
}).on("error", function() {
callback(null);
});
}
How do I send the data received from NodeJS to the client side?
EDIT
i found the solution :
exports.sendPdf = function(req, res) {
var donneRecu = req.body;
console.log(donneRecu['lien']);
var url = donneRecu['lien']; //pdf link
http.get(url, function(response) {
var chunks = [];
response.on('data', function(chunk) {
console.log('downloading');
chunks.push(chunk);
});
response.on("end", function() {
console.log('downloaded');
var jsfile = new Buffer.concat(chunks).toString('base64');
console.log('converted to base64');
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('content-type', 'application/pdf');
res.send(jsfile);
});
}).on("error", function() {
callback(null);
});
}
next in my angular controller:
var pdf = $scope.base64ToUint8Array(data);
PDFJS.getDocument(pdf).then(functiongetPdfHelloWorld(_pdfDoc) {
$scope.pdfDoc = _pdfDoc;$scope.renderPage($scope.pageNum); });
i found the solution :
exports.sendPdf = function(req, res) {
var donneRecu = req.body;
console.log(donneRecu['lien']);
var url = donneRecu['lien']; //pdf link
http.get(url, function(response) {
var chunks = [];
response.on('data', function(chunk) {
console.log('downloading');
chunks.push(chunk);
});
response.on("end", function() {
console.log('downloaded');
var jsfile = new Buffer.concat(chunks).toString('base64');
console.log('converted to base64');
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('content-type', 'application/pdf');
res.send(jsfile);
});
}).on("error", function() {
callback(null);
});
}
next in my angular controller:
var pdf = $scope.base64ToUint8Array(data);
PDFJS.getDocument(pdf).then(functiongetPdfHelloWorld(_pdfDoc) {
$scope.pdfDoc = _pdfDoc;$scope.renderPage($scope.pageNum); });
I too faced the same situation and the below code helped me.
var fs = require("fs");
var file = fs.createReadStream('./public/modules/datacollectors/output.pdf');
var stat = fs.statSync('./public/modules/datacollectors/output.pdf');
res.setHeader('Content-Length', stat.size);
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=quote.pdf');
file.pipe(res);
Hope it helps.
Related
New to node and trying not to do any callback hell.
I have two files
routes.js
fetch.js
//routes.js
var fetchController = require("../lib/mtl_fetcher/fetcher_controller");
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.send(fetchController.getAllTransgressor(function(results) {
return results.end();
}))
});
module.exports = router;
and
//fetch.js
var http = require('http');
var config = require('./config')
var Iconv = require('iconv').Iconv
module.exports.getAllTransgressor = function(callback) {
var req = http.get(config.urlOptions.host, function (response) {
var bufferChunk = [];
var str
if(response.statusCode == 200) {
response.on('data', function(chunk) {
bufferChunk.push(chunk);
})
response.on('end', function(callback) {
var iconv = Iconv('latin1', 'UTF-8');
str = iconv.convert(Buffer.concat(bufferChunk)).toString();
console.log(str)
});
} else {
console.log("handle this")
}
});
req.on("error", function(err) {
callback(err);
});
callback(req)
}
So the goal is to fetch and then show what has been fetch to the screen. The ressource is XML base.
Doing all of this in one block (routes.js) works, but when I try to refactor and set up some modularity my str just shows in shell stdout.
Using req.end() does not send the content back.
Firstly, you need to send inside the callback, where the result is actually available, as you can't return from an asynchronous function
router.get('/', function(req, res, next) {
fetchController.getAllTransgressor(function(error, results) {
if ( error ) {
// handle errors
} else {
res.send(results);
}
});
});
The same goes for the callback function, it has to be called when the data is available, after the request and parsing
module.exports.getAllTransgressor = function(callback) {
var req = http.get(config.urlOptions.host, function(response) {
var bufferChunk = [];
if (response.statusCode == 200) {
response.on('data', function(chunk) {
bufferChunk.push(chunk);
});
response.on('end', function() {
var iconv = Iconv('latin1', 'UTF-8');
var str = iconv.convert(Buffer.concat(bufferChunk)).toString();
callback(null, str); // here, stuff is available
});
} else {
callback('Did not return 200', err);
}
});
req.on("error", function(err) {
callback(err, null);
});
}
I am building file management system using pure node.js and html.
app.js and requestHandler.js seems to be working fine for other things like get/post request with parameters.
I can accept the parameters in requestHandler.js using parameters object. For example, if I want to access username, i can access using parameters.username.
For file upload functionality, I did following in JS.
Problem with following code is, file is getting damaged while saving for image files. but if i upload txt file, that is getting saved properly.
What i am doing wrong for image file?
$("#upload-file").on("click", function(){
var file = document.getElementById('file'); //Files[0] = 1st file
file = file.files[0];
var reader = new FileReader();
reader.readAsText(file, 'UTF-8');
reader.onload = function(event){
var result = event.target.result;
var fileName = document.getElementById('file').files[0].name; //Should be 'picture.jpg'
$.post('/api/upload', { data: result, name: fileName }, function(){
});
};
//reader.onloadstart = ...
//reader.onprogress = ... <-- Allows you to update a progress bar.
//reader.onabort = ...
//reader.onerror = ...
//reader.onloadend = ...
});
app.js
var http = require('http');
var fs = require('fs');
var path = require('path');
var qs = require('querystring');
var api = require('./requestHandler.js');
var server = http.createServer(function (req, res) {
if(req.url != "/") {
var requestUrl = req.url;
if(requestUrl.indexOf("api") != -1) {
var element = {};
var apiClass = requestUrl.split("/");
var apiClass = apiClass[2].split("?");
if (req.method == 'POST') {
var body = '';
req.on('data', function (data) {
body += data;
if (body.length > 1e6) {
req.connection.destroy();
}
});
req.on('end', function () {
var element = qs.parse(body);
api.handle(apiClass[0], element, res);
});
} else {
var query = req.url;
query = query.split("?");
if(query.length == 2) {
query = query[1].split("&");
query.forEach(function(item, index){
item = item.split("=");
element[item[0]] = item[1];
});
}
api.handle(apiClass[0], element, res);
}
} else {
fs.readFile(__dirname + requestUrl, function (err, data) {
switch(path.extname(requestUrl)) {
case ".css":
res.writeHead(200, { 'Content-Type': 'text/css' });
break;
case ".js":
res.writeHead(200, { 'Content-Type': 'text/javascript' });
break;
case ".woff":
res.writeHead(200, { 'Content-Type': 'application/font-woff' });
break;
case ".ttf":
res.writeHead(200, { 'Content-Type': 'application/x-font-ttf' });
break;
case ".eot":
res.writeHead(200, { 'Content-Type': 'application/vnd.ms-fontobject' });
break;
case ".svg":
res.writeHead(200, { 'Content-Type': 'application/svg+xml' });
break;
}
res.end(data, 'utf-8');
res.end();
});
}
} else {
fs.readFile('index.html', function (err, data) {
res.writeHead(200, {
'Content-Type': 'text/html',
'Content-Length': data.length
});
res.write(data);
res.end();
});
}
});
server.listen(888);
console.log("server listening on 888");
requestHandler.js
var fs = require('fs');
module.exports = {
handle: function (requestURL, parameters, res) {
switch(requestURL) {
case "upload":
fs.writeFile("./files/" + parameters.name, parameters.data, 'binary', function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
break;
}
}
};
I try to learn nodeJS and AngularJS using Clash of clan API available here https://developer.clashofclans.com/#/
My JSON api's return is truncated and i don't know how get the full response.
there is my app.js wrinting with node and express :
var express = require('express')
, https = require('https')
, bodyParser = require('body-parser')
, request = require('request')
, app = express()
, http_port = 3000;
app.use(express.static(__dirname + '/public'));
app.use(bodyParser());
var options = {
host: 'api.clashofclans.com',
port: 443,
path: '/v1/clans/' + encodeURIComponent("#PP8JC9RQ"),
headers : {
accept : "application/json",
authorization : "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiIsImtpZCI6IjI4YTMxOGY3LTAwMDAtYTFlYi03ZmExLTJjNzQzM2M2Y2NhNSJ9.eyJpc3MiOiJzdXBlcmNlbGwiLCJhdWQiOiJzdXBlcmNlbGw6Z2FtZWFwaSIsImp0aSI6ImQ4Njg1OGFhLWQzZTUtNDNiOC05MTM1LTBjNzI1ZjI4OGFiMiIsImlhdCI6MTQ1NjMwMTE5MSwic3ViIjoiZGV2ZWxvcGVyLzk1YWM0YjdmLTY5NTQtMDE3MC01ZjAyLTcxNjY1ZDMzYjUwNyIsInNjb3BlcyI6WyJjbGFzaCJdLCJsaW1pdHMiOlt7InRpZXIiOiJkZXZlbG9wZXIvc2lsdmVyIiwidHlwZSI6InRocm90dGxpbmcifSx7ImNpZHJzIjpbIjg3LjIzMS4yMTMuMTU0Il0sInR5cGUiOiJjbGllbnQifV19.SYqeSAF-0_bM1eS2-hnovvj5j-I0SQpdr_kySIiBKw9OkrNuBzZAOAOkiH3fzdKSkcHaJfXzWdXr8JozFfAmJA"
},
method: 'GET'
};
// Route par défaut
app.get("/members", function(req, res) {
console.log("-------------------------------------\n\nroot path !! Let's get clan infos from coc api\n\n-------------------------------------");
var req = https.request(options, function(response){
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
// in console JSON is full but in my html JSON is truncated..
res.send(chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
});
app.listen(http_port,function(){
console.log("Listening on " + http_port);
});
If someone can teach to a nook :)
Your code is sending the first chunk of the response immediately back to the user. You need to wait until the entire HTTP response is done. Try something like this:
app.get("/members", function(req, res) {
var req = https.request(options, function(response){
var httpResult = '';
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
httpResult += chunk;
});
response.on('end', function() {
res.send(httpResult);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
});
See how I append to a var each time the data event is called and when it is done - then I send the output.
Because you use send method instead write (send non-streaming). Try this:
app.get("/members", function(req, res) {
https.request(options, function(response){
response.on('data', function (chunk) {
res.write(chunk);
});
response.on('end', function () {
res.end();
});
}).end();
});
response is a stream, you can simply pipe it to res:
app.get("/members", function(req, res) {
https.request(options, function(response) {
response.pipe(res);
});
});
i am trying to diplay binary data image in angularjs html form.i am geeting two responses.i dono how to avoid that i have enclosed my screetshot.1st one is my response again it passing bad response please some one help me out.i have enclose client and server side controller
client side controller
'use strict';
/**
* #ngdoc object
* #name test1.Controllers.Test1Controller
* #description Test1Controller
* #requires ng.$scope
*/
angular
.module('test1')
.controller('Test1Controller', [
'$scope','$http' ,'$location','$window',
function($scope,$http, $location,$window)
{
$scope.image = {};
var image="download.jpg";
$http.get('*/upload/'+image).success(function(data,status,response)
{
console.log(data);
$scope.image=data;
var testJpg = $scope.image;
document.getElementById("myimage").src = testJpg;
});
}
]);
backend controller
'use strict';
var mongoose = require('mongoose'),
_ = require('lodash');
var Grid = require('gridfs-stream');
Grid.mongo = mongoose.mongo;
var gfs = new Grid(mongoose.connection.db);
exports.create = function(req, res) {
console.log(req.files.filefield);
var part = req.files.filefield;
var writeStream = gfs.createWriteStream({
filename: part.name,
mode: 'w',
content_type:part.mimetype
});
writeStream.on('close', function() {
return res.status(200).send({
message: 'Success'
});
});
writeStream.write(part.data);
writeStream.end();
};
exports.read = function(req, res) {
gfs.files.find({ filename: req.params.filename }).toArray(function (err, files) {
if(files.length===0){
return res.status(400).send({
message: 'File not found'
});
}
res.writeHead(200, {'Content-Type': files[0].contentType});
var readstream = gfs.createReadStream({
filename: files[0].filename
});
var bufs=[];
readstream.on('data', function(data) {
// res.write(data);
bufs.push(data);
}).on('end', function() {
// res.end();
var fbuf = Buffer.concat(bufs);
var base64 = (fbuf.toString('base64'));
//console.log(base64 );
res.end('"data:image/jpeg;base64,' + base64 + '";');
});
readstream.on('error', function (err) {
console.log('An error occurred!', err);
throw err;
});
});
};
<div ng-controller="Test1Controller" >
<img ng-src="" id="myimage" />
</div>
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:
mp3 download
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.