I'm trying to upload an external url to my server. Here's what I got so far
var fs = require('fs');
var request = require('request');
var path = require('path');
const imagesFolder = 'downloadedAssets/imgs';
function download(url, dest, filename, cb) {
var file = fs.createWriteStream(dest + "/" + filename + path.extname(url));
request( {url: url}, function(err, response) {
if(err) {
console.log(err.message);
return;
}
response.pipe(file);
file.on('error', function(err) {
console.log(err.message);
file.end();
});
file.on('finish', function() {
file.close(cb);
});
});
}
and then executing the function...
var url = 'http://pngimg.com/uploads/spongebob/spongebob_PNG44.png';
download(url, imagesFolder, 'sponge', function onComplete(err) {
if (err) {
console.log(err.message);
} else {
console.log('image uploaded to server');
}
});
This doesn't throw any errors, and it creates a file name sponge.png, but the file is empty. Any idea why?
You might have mixed up the examples on the official website
Try using pipe() like below.
function download(url, dest, filename, cb) {
var file = fs.createWriteStream(dest + "/" + filename + path.extname(url));
request( {url: url}).pipe(file);
}
Related
How to download audio file from URL and store it in local directory?
I'm using Node.js and I tried the following code:
var http = require('http');
var fs = require('fs');
var dest = 'C./test'
var url= 'http://static1.grsites.com/archive/sounds/comic/comic002.wav'
function download(url, dest, callback) {
var file = fs.createWriteStream(dest);
var request = http.get(url, function (response) {
response.pipe(file);
file.on('finish', function () {
file.close(callback); // close() is async, call callback after close completes.
});
file.on('error', function (err) {
fs.unlink(dest); // Delete the file async. (But we don't check the result)
if (callback)
callback(err.message);
});
});
}
No error occured but the file has not been found.
Duplicate of How to download a file with Node.js (without using third-party libraries)?, but here is the code specific to your question:
var http = require('http');
var fs = require('fs');
var file = fs.createWriteStream("file.wav");
var request = http.get("http://static1.grsites.com/archive/sounds/comic/comic002.wav", function(response) {
response.pipe(file);
});
Your code is actually fine, you just don't call the download function. Try adding this to the end :
download(url, dest, function(err){
if(err){
console.error(err);
}else{
console.log("Download complete");
}
});
Also, change the value of dest to something else, like just "test.wav" or something. 'C./test' is a bad path.
I tried it on my machine and your code works fine just adding the call and changing dest.
Here is an example using Axios with an API that may require authorization
const Fs = require('fs');
const Path = require('path');
const Axios = require('axios');
async function download(url) {
let filename = "filename";
const username = "user";
const password = "password"
const key = Buffer.from(username + ':' + password).toString("base64");
const path = Path.resolve(__dirname, "audio", filename)
const response = await Axios({
method: 'GET',
url: url,
responseType: 'stream',
headers: { 'Authorization': 'Basic ' + key }
})
response.data.pipe(Fs.createWriteStream(path))
return new Promise((resolve, reject) => {
response.data.on('end', () => {
resolve();
})
response.data.on('error', () => {
reject(err);
})
})
}
I want to resize my images before I upload them to s3 amazon.
I need 3 diffrent size : resizing (original image, thumbnail, web size) .
How can I do this?
How do I get the path of my image that was past with method POST?
This is my code:(to upload image to s3 amazon with node js)
app.post('/upload', function(request, response) {
var ext
, hash
, form = new formidable.IncomingForm()
, files = []
, fields = [];
form.keepExtensions = true;
form.uploadDir = 'tmp';
form.on('fileBegin', function(name, file) {
ext = file.path.split('.')[1];
hash = hasher();
file.path = form.uploadDir + '/' + hash;
});
form.on('field', function(field, value) {
fields.push([field, value]);
}).on('file', function(field, file) {
files.push([field, file]);
}).on('end', function() {
fs.readFile(__dirname + '/../tmp/' + hash, function(error, buf) {
var req = client.put('/images/' + hash + '.png', {
'x-amz-acl': 'private',
'Content-Length': buf.length,
'Content-Type': 'image/png'
});
req.on('response', function(res){
var image = new S3({
hash : hash,
url : req.url
});
image.save(function(error, result) {
if (error) {
console.error(error);
} else {
response.redirect('http://' + request.headers.host + '/' + hash);
};
})
});
req.end(buf);
});
});
form.parse(request);
});
Use graphicsmagick, imagemagick for that. Also gm module. Link
Example:
gm(buf)
.resize(100, 100)
.toBuffer('PNG',function (err, buffer) {
if (err) return handle(err);
console.log('done!');
upload(buffer,function(err){
if(!err)
console.log("uploaded")
}
}) //use buffer for upload
function upload(buffer,callback){
s3bucket = new AWS.S3();
params={
Bucket: bucketName,
Key: folder + '/' + fileName,
Body: buffer,
ACL: 'public-read'
}
s3bucket.putObject(params,function(err)....
}
HTML component:
*<*input type="file" class="hidden" id="logoFile">// remove *
JAVASCRIPT:
file = document.getElementById('logoFile').files[0];
image = new Parse.File("image.jpg", file); // I am using Parse. You can use other Node.js modules.
You can set size as per your wish.
Try this:
image.resize(200, 200, function(err, image){
// encode resized image to jpeg and get a Buffer object
image.toBuffer('jpg', function(err, buffer){
// save buffer to disk / send over network / etc.
});
});
I am using node.js on digital ocean and trying to run a file upload / download server.
To make sure the server runs in the background and does not quit on error, I am using the following
nohup nodejs server.js &
I am using nodejs instead of the node command because that is what digital ocean recommends.
This server is almost exlusively for uploading and downloading files. This works, for about two files, but then the server crashes with the following error:
"terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc"
I have no idea what is causing this, and I would appreciate any help. Preventing the crash would be great but also making it so the node server would not crash would also be great. I thought that is what nohup does, but apparently not. (I also haven't been able to get forever working correctly).
Here is the code for my server:
var http = require('http'),
url = require('url'),
util = require('util'),
path = require('path'),
fs = require('fs'),
qs = require('querystring');
var formidable = require('formidable'),
mime = require('mime');
var account = {username: 'test', password: 'etc'};
var accounts = [account],
port = 9090,
function dirTree(filename) {
var stats = fs.lstatSync(filename),
info = {
name: path.basename(filename),
path: ip + ':' + port + '/uploads/finished/' + path.basename(filename),
type: mime.lookup(filename).substring(0, 5)
};
if (stats.isDirectory()) {
info.type = "folder";
info.children = fs.readdirSync(filename).map(function(child) {
return dirTree(filename + '/' + child);
});
}
return info;
}
http.createServer(function(request, response) {
if(request.method.toLowerCase() == 'get') {
var filePath = './content' + request.url;
if (filePath == './content/') {
filePath = './content/home.html';
}
if (filePath == './content/feed') {
a = dirTree('./content/uploads/finished');
response.end(JSON.stringify(a));
}
var extname = path.extname(filePath);
var contentType = mime.lookup(extname);
fs.exists(filePath, function (exists) {
if (exists) {
fs.readFile(filePath, function (error, content) {
if (error) {
response.writeHead(500);
response.end();
}
else {
response.writeHead(200, {'Content-Type': contentType});
response.end(content, 'utf-8');
}
})
} else {
response.writeHead(404);
response.end();
}
});
}
if (request.method.toLowerCase() == 'post') {
var form = new formidable.IncomingForm;
if (request.url == '/verify') {
form.parse(request, function (err, fields, files) {
for (i = 0; i < accounts.length; i++) {
if (fields.username == accounts[i].username && fields.password == accounts[i].password) {
fs.readFile('./content/uploadForm.html', function (error, content) {
if (error) {
response.end('There was an error');
} else {
response.end(content);
}
});
} else {
fs.readFile('./content/invalidLogin.html', function (error, content) {
if (error) {
response.end('There was an error');
} else {
response.end(content);
}
});
}
}
});
} else if (request.url == '/upload') {
var oldPath,
newPath,
fileName;
form.uploadDir = './content/uploads/temp/';
form.keepExtensions = true;
form.parse(request, function (err, fields, files) {
type = files['upload']['type'];
fileName = files['upload']['name'];
oldPath = files['upload']['path'];
newPath = './content/uploads/finished/' + fileName;
});
form.on('end', function () {
fs.rename(oldPath, newPath, function (err) {
if (err) {
response.end('There was an error with your request');
console.log('error')
} else {
response.end('<h1>Thanks for uploading ' + fileName + '<h1>');
}
});
});
}
}
}).listen(port);
console.log('listening on ' + port);
It looks like your script is just run out of the available memory.
Most likely you upload or download very large file and you read complete file in memory while receiving or sending.
You should rewrite you code using stream operations and process files chunk-by-chunk instead.
So I have been wondering how to save an image to node.js server without the use of express.(just learning node and want to make everything myself to learn node better, without express).
So far I have a form with the image as only input which I send with a post request. This is what I have so far on my server, which does not log anything.
if(req.method === 'POST') {
if (req.url === '/upload') {
req.on('error', function(e) {
console.log('Problem with request: ' + e.message);
});
res.writeHead(200, {'Content-Type': 'image/jpg; charset=utf8'});
req.on('data', function (chunk) {
fs.writeFile(__dirname + "/uploads/dada.jpg", chunk, function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
});
}
}
This is my form:
<form method="post" action="/upload" enctype="multipart/form-data">
EDIT: I fixed most of the problems, but the file is only saved as an image, but cannot be viewed like one. (Something is wrong with the content-type I guess, but don't know how to fix it)
Here is fiddle of my whole app. I know I need to separate it in different modules, but I will do that later
I completely forgot about this old question but now that I see it has quite some views, here is the solution I found:
var port = 1357;
var http = require('http'),
path = require('path'),
mime = require('mime'),
fs = require('fs'),
GUID = require('GUID'),
formidable = require('formidable'),
util = require('util');
var app = http.createServer(function (req, res) {
if (req.method === 'POST') {
if (req.url === '/upload') {
req.on('error', function (e) {
console.log('Problem with request: ' + e.message);
});
var fileDirectory = __dirname + '/db/',
form = new formidable.IncomingForm();
form.keepExtensions = true;
form.uploadDir =fileDirectory;
form.parse(req, function (err, fields, files) {
if (err) throw (err);
var pic = JSON.stringify(util.inspect(files)),
upIndx = pic.indexOf('db'),
path = pic.slice(upIndx + 6, upIndx + 42);
res.writeHead(200, {
'Content-Type': 'text/html'
});
fs.readFile('views/index.html', function (err, page) {
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.write(page);
res.write('<div>Download Link: </div><div>' + fileDirectory + path + '</div>');
res.end();
});
});
}
} else {
//not important for question, handle other request
}
});
app.listen(port);
console.log('Server running on port: ' + port)
I tried to follow an example on the web for creating a NodeJS server and router, but have ran into problems. What follows is primarily the example with a bit of other code.
Index.js
var server = require("./server");
var router = require("./router");
server.start(router.route);'
Router.js
var fs = require("fs");
function route(filename) {
fs.readFile(filename, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
console.log("About to route a request for " + filename);
data = JSON.parse(data);
})
}
exports.route = route;
Server.js
var http = require('http');
var url = require("url");
function start(route) {
function onRequest(request, response) {
var filename = request.url.substr(1);
// call for specific json file here
if (filename == "favicon.ico") {
response.writeHead(200, {'Content-Type': 'image/x-icon'} );
response.end();
console.log('favicon requested');
return;
}
else {
filename += ".json";
console.log("Request for " + filename + " received.");
response.writeHead(200, { 'Content-Type': 'application/json', "Access-Control-Allow-Origin":"*" });
response.write("" + route(filename),0,4);
response.end();
}
}
http.createServer(onRequest).listen(8124);
}
exports.start = start;
console.log('Server running at http://127.0.0.1:8124/');
The question I have is, among others, how does the route command work?
What I get when I browse to the server is 'undefined'. How do I get the actual json from the Router?
I tried: var result = route(filename); but that failed badly.
In essence, how to get the data from the router and write it to the response. If you haven't guessed, javascript and NodeJS is rather new to me.
Any pointers would be greatly appreciated.
Thank you.
Your route function has an async method, fs.readFile. You'll need to pass in a callback to the route function, so that it can return the data properly. Otherwise, route will return immediately with no data (since it's async) regardless if you have a return statement inside readFile.
router.js
function route(filename, callback) {
fs.readFile(filename, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
console.log("About to route a request for " + filename);
data = JSON.parse(data);
callback(data); // Call this function after the data is grabbed.
})
}
server.js portion:
response.writeHead(200, { 'Content-Type': 'application/json', "Access-Control-Allow-Origin":"*" });
route(filename, function (data) {
response.write("" + JSON.stringify(data),0,4);
response.end();
});