I'm trying to read a PDF from a URL and display it to a user's browser (via the passed in 'response' object). I've tried to use the code below and it works sometimes, but generally fails:
function writePdfToBrowser(url, response) {
http.get(url, function(res) {
logger.verbose('about to start download...');
var chunks = [];
res.on('data', function(chunk) {
chunks.push(chunk);
});
res.on("end", function() {
logger.verbose('downloaded');
var buffer = new Buffer.concat(chunks);
//write downloaded pdf to the original response
response.write(buffer);
//response.send(buffer);
response.end();
});
}).on("error", function() {
logger.error("error!");
});
}
In the new page where I attempted to load the pdf it would just say "Failed to load pdf".
I'm new to Node, so not sure where the problem lies, any ideas? Anyone have any working code to do the same thing?
Thank you for any help!
Mark
Use piping:
function pipe(url, res) {
var request = http.get(url, function(response) {
res.writeHead(response.statusCode, response.headers)
response.pipe(res);
});
request.on('error', function(error){
res.statusCode = 500;
res.end(error.message);
});
}
... and please provide next time more information about what and how it fails, some logs, inspect response im browser before. And so on..
Related
I can't reach my value until my function is ending.. I tried callbacks but it seems to doesn't work..
exports.helloHttp = function helloHttp (req, res) {
var url = "https://api.coindesk.com/v1/bpi/currentprice.json";
var btcValue
require('https').get(url, function(res, btcValue){
var body = '';
res.on('data', function(chunk){
body += chunk;
});
res.on('end', function(){
btcValue = JSON.parse(body);
callback(btcValue);
});
}).on('error', function(e){
console.log("Got an error: ", e);
});
console.log("Got a respons ", btcValue);
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ "speech": response, "displayText": response
}));
};
Thanks a lot in advance
I've written a standalone example based on your code:
var http = require('http'),
https = require('https');
http.createServer(function(req, res) {
// You can largely ignore the code above this line, it's
// effectively the same as yours but changed to a standalone
// example. The important thing is we're in a function with
// arguments called req and res.
var url = 'https://api.coindesk.com/v1/bpi/currentprice.json';
var request = https.get(url, function(response) {
var body = '';
response.on('data', function(chunk) {
body += chunk;
});
response.on('end', function() {
// TODO: handle JSON parsing errors
var btcValue = JSON.parse(body);
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({
btcValue: btcValue
}));
});
});
request.on('error', function(e) {
console.error(e);
});
// Runs this example on port 8000
}).listen(8000);
The most important change is moving the code for handling our response (res) into the 'end' listener of the coindesk response. That call to coindesk is asynchronous so we have to wait for the 'end' event before we try to act on it.
You reference a variable called response twice when building your JSON. Your code didn't define response but I've assumed that it is supposed to be related to the btcValue coming back from the call to coindesk. I wasn't sure exactly what you wanted there so I've just wrapped btcValue in another object for demonstration purposes.
In your original code you had this line:
require('https').get(url, function(res, btcValue){
That second argument, which you've called btcValue, doesn't exist so it will just be set to undefined.
I've changed send to end but that isn't a significant change. I assume you're using Express (which provides a send method) whereas my example is not.
I want to get the html of this page for parsing(click the link to understand what content i want to get).
750-bond list
Here's my code to request this page content
var https = require("https");
var fs = require("fs");
var options = {
hostname: "www.prizebond.net",
port: 443,
path: "/dlist.php?num=455",
method: "GET"
};
var response = "";
var req = https.request(options, function (res) {
res.setEncoding("UTF-8");
console.log(res.statusCode);
res.on("data", function (chunk) {
response += chunk;
});
res.on("end", function () {
fs.writeFile("750-bond.html", response, function (err) {
if (err) {
console.log(err.message);
}
console.log("File downloaded");
});
console.log("end");
});
});
req.end();
Now the problem is that in my 750-bont.html file, I am getting the weird the
result of "Checking your browser before accessing the prizebond.net" not the
original content. Here's the screenshot what I got when I open the 750-
bond.html file in browser.
What I am doing wrong? And how can I get the original content of this webpage?
You can't, unless you write something more sophisticated, but you probably shouldn't.
The purpose of Cloudflare-protection is to prevent what you are trying to realize unfortunately.
You could look into a possibility to access whatever you want to access by a public API or something that prizebond.net provides for example.
I read the nodejs document,it says that the only difference between these two function is that http.get will execute req.end automatically.But I got a weird question.I write some codes like these:
http.get(url,function(res){
var data="";
res.on('data',function(chunk){
data+=chunk;
});
res.on('end',function(){
console.log(data);
});
}).on("error",function(){
});
in this place,the data works fine.But when I use http.request,something is wrong.
var pReq = http.request(options, function(pRes) {
var data=" ";
pRes.on('data',function (chunk) {
data+=chunk;
});
pRes.on('end',function() {
console.log(data)
});
}).on('error', function(e) {
});
in this place,I always got Garbled.I'm new in node,are there any mistakes about the sencode one?
On my node express server, I am receiving a pdf file. I am using the below code to get the pdf contents from the request
var data = new Buffer('');
request.on('data', function (chunk) {
data = Buffer.concat([data, chunk]);
});
request.on('end', function() {
console.log('PDF data is '+JSON.stringify(data));
});
Now that PDF content is available on node, I need to send it as it is to a J2EE server. In order to do that, I am first saving the PDF file in the node server, reading it from the node server and then piping it to request.post (https://github.com/request/request)
var req = require('request');
fs.writeFile('abc.pdf', data, 'binary', function(err) {
if (err) {
console.log('Error ' + JSON.stringify(err) );
throw err;
}
var source = fs.createReadStream('abc.pdf');
//send our data via POST request
source.pipe(req.post('http://'+j2ee_host+':'+j2ee_port+'/myjavaapp/Upload')
});
This works fine. However, I feel the part of saving the PDF file on the node server and then reading it is (before posting to the J2EE server using request module) is completely unnecessary, as I am not making any changes to the file.
Once I have the PDF contents in 'data' variable, I would like to directly post them to the J2EE server. However, I have not been able to find a way to use the request module to directly post file contents. I have seen some examples related to POST using request module but they refer to formData. In my case, I don't have formData but instead reading the file from request and directly posting it to the J2EE server.
Is there a way to achieve this and avoid the file write and read?
EDIT
Below is my complete code
function upload(request, response) {
var data = new Buffer('');
request.on('data', function (chunk) {
data = Buffer.concat([data, chunk]);
});
request.on('end', function () {
fs.writeFile('abc.pdf', data, 'binary', function(err){
if (err) {
console.log('Error ' + JSON.stringify(err) );
throw err;
}
var source = fs.createReadStream('abc.pdf');
source.pipe(req.post('http://'+j2ee_host+':'+j2ee_port+'/myj2eeapp/Upload'));
})
})
}
You can pipe directly from the data request to the servlet
var req = require('request');
function upload(request, response) {
var target = req.post('http://'+j2ee_host+':'+j2ee_port+'/myjavaapp/Upload');
request.pipe(target);
target.on('finish', function () {
console.log('All done!');
//send the response or make a completed callback here...
});
}
I would like to download a file, write it to a temporary file, read it and give the readFileSync Buffer to a function. I tried this:
var file = fs.createWriteStream("temp.pdf")
var request = http.get(linkArray[1], function(response) {
response.on('data', function(data){
file.write(data)
}).on('end', function(){
postData(fs.readFileSync('temp.pdf'))
})
});
Sometimes it works, but sometimes it doesn't - my guess is that the file isn't written completely, when it is read. (But than the 'end' event shouldn't be fired ?!
As you can see, I would like to download a bunch of files and do this. Do you have any advise how to solve this? Maybe this isn't the best way to solve this...
You shouldn't link streams with on('data' you should use pipe. Pipe will link the streams data events to writes and end events to ends.
var file = fs.createWriteStream("temp.pdf");
var request = http.get(linkArray[1], function(response) {
response.pipe(file).on('close', function(){
postData(fs.readFileSync('temp.pdf'));
});
});
also you should use https://github.com/mikeal/request
var request = require('request');
request.get(linkArray[i], function (err, response, body) {
postData(body);
});
or
var request = require('request');
var file = fs.createWriteStream("temp.pdf");
request.get(linkArray[i]).pipe(file).on('close', function () {
postData(fs.readFileSync('temp.pdf'));
});
You need to call file.end(); at the top of your .on('end', ...) handler. The end() method itself is asynchronous, though, so you'll want to read the file once that's complete. E.g.,
var file = fs.createWriteStream("temp.pdf")
var request = http.get(linkArray[1], function(response) {
response.on('data', function(data){
file.write(data)
}).on('end', function(){
file.end(function() {
postData(fs.readFileSync('temp.pdf'))
});
})
});