Uploading a photo from a form using node.js - javascript

I'm quite new to node and need some guidance and help. Before I go any further, I'm trying to do this without any other frameworks like Express. The situation is the following:
I've have a form where a user can upload a photo to a server running in node. The form has the following properties
<form action="/newImages/" method="post" enctype="multipart/form-data">
File goes : <input type="file" name="fileName"><br>
<input type="submit" value="Submit">
</form>
The form input is handled by this code
if (req.method == 'POST' && req.url == '/newImages/') {
console.log("Inside Post method");
var body = ''
req.on('data', function(data) {
body += data
})
req.on('end', function() {
var note = querystring.parse(body)
console.log(note)
fs.writeFile("./test.jpg",body, function(err){
if(err)
{
console.log(err);
}
else
{
console.log("The Picture was saved");
}
})
res.writeHead(302, {
'Content-Type':'text/plain',
'location':'/index.html'});
res.end('Found!');
})
}
However, something tells me I need to parse the data differently, as the output of this is unreadable. It looks like :
"\n\r\n����\u0000\u0010JFIF\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0000��\u0000C\u0000\b\u0006\u0006\u0007\u0006\u0005\b\u0007\u0007\u0007\t\t\b\n\f\u0014\r\f\u000b\u000b"
Any ideas on how to get this to work? I should also note that I upload .jpg's only.
Thanks

I think that you are wrong when you save your picture. You don't need to use fs.writeFile() but fs.rename.
This cose works in my app.js:
app.post('/upload', function (req, res) {
var tempPath = req.files.file.path,
name = '',
targetPath = '';
fileExist = true;
fileNumber = 0;
var fileType = path.extname(req.files.file.name);
var fileName = path.basename(req.files.file.name,fileType);
while (fileExist) {
fileNumber_str = fileNumber.toString();
var current = fileName + "_" +fileNumber_str + fileType;
console.log("Controllo per "+current);
if (fs.existsSync(__dirname + "/images/orig/" + current)) {
console.log("--> Esiste");
fileNumber++;
} else {
var newPath = __dirname + "/images/orig/" + current;
console.log("nuovo nome : "+newPath);
fs.rename(tempPath, newPath, function(err) {
if (err) throw err;
//Ora creo il thumb
console.log("Upload completed!");
});
break;
}
}
res.redirect("/");
res.end();
});
Take a look.
M.

It seems that you cannot parse multipart data with querystring.parse.
You have to write your own parser or use third-party module, like node-multiparty.
With multiparty module the code will be like this:
if (req.method == 'POST' && req.url == '/newImages/') {
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
var tmp = files.fileName[0].path;
fs.rename(tmp, '/your/dir/img.jpg', function(err) {
if (err) throw err;
console.log('success');
});
res.end('Found!');
});
}

Related

how can i load my js function from js file on my nodejs server?

I'm working on a small website, I'm a beginner in javascript and nodejs, I create a small server with nodejs but I do not know how to load my file.js in the server help please.
this is my server :
enter code here
let http = require('http');
let fs = require('fs');
let path = require('path');
http.createServer(function(req, res)
{
if(req.url === "/")
{
fs.readFile("index.html", "UTF-8", function(err, html)
{
res.writeHead(200, {"Content-Type": "text/html"});
res.end(html);
});
}else if(req.url.match("\.css$"))
{
var cssPath = path.join(__dirname, '', req.url);
var fileStream = fs.createReadStream(cssPath, "UTF-8");
res.writeHead(200, {"Content-Type": "text/css"});
fileStream.pipe(res);
}else if(req.url.match("\.png$")){
var imagePath = path.join(__dirname, '', req.url);
var fileStream = fs.createReadStream(imagePath);
res.writeHead(200, {"Content-Type": "images/png"});
fileStream.pipe(res);
}else if (req.url.match("\.jpg$")) {
var imagePath = path.join(__dirname, '', req.url);
var fileStream = fs.createReadStream(imagePath);
res.writeHead(200, {"Content-Type": "images/jpg"});
fileStream.pipe(res);
}
else
{
res.writeHead(404, {"Content-Type": "text/html"});
res.end("No Page Found");
}
}).listen(3000, '127.0.0.1');
and this is a part from my javascript file
$(function(){
let navMain=document.querySelector('nav');
let ul=document.getElementById('mainUl');
let li=document.createElement('li');
let a=document.createElement('a');
let login=document.createTextNode('Login');
$(window).on('scroll',function(){
const navMainTopMesure=navMain.offsetTop;
if($(window).scrollTop() && window.scrollY>=navMainTopMesure){
$('nav').addClass('fixed');
a.appendChild(login);
li.appendChild(a);
ul.appendChild(li);
a.addEventListener('click',function(){
document.querySelector('.login').style.display='flex';
});
return 0;
}else{
$('nav').removeClass('fixed');
ul.removeChild(li);
}
})
});
$(function(){
window.addEventListener('click',function(e){
if(e.target == document.querySelector('.register')){
document.querySelector('.register').style.display='none';
}
})
window.addEventListener('click',function(e){
if(e.target == document.querySelector('.login') ){
document.querySelector('.login').style.display='none';
}
})
let date =new Date();
document.getElementById('date').innerHTML=date.toDateString();
document.querySelector('.sign-up').addEventListener('click',function(){
document.querySelector('.register').style.display='flex';
})
document.querySelector('.closeRegister').addEventListener('click',function(){
document.querySelector('.register').style.display='none';
})
document.querySelector('.sign-in').addEventListener('click',function(){
document.querySelector('.login').style.display='flex';
})
document.querySelector('.closeLogin').addEventListener('click',function(){
document.querySelector('.login').style.display='none';
})
$('.mobile-nav').on('click',function(){
$('.nav-main ul').toggleClass('drop');
$('.mobile-nav i').toggleClass('fa-times');
})
});
function smoothScroll(target,duration)
{
var target = document.querySelector(target);
var targetposition = target.getBoundingClientRect().top;
var startposition = window.pageYOffset;
var distance = targetposition-startposition;
var starttime = null;
i just want to execute my function in javascripte file in my server.
my probleme when i execute the html file on the localhost in the browser evry think is okey but any javascript event happend
What you want to do is create a folder in your main app directory, called 'frontend' or 'src' or 'public' and in that folder create the directory that will be used by your index.html file. Throw your JS file in there wherever you want it.
In your main server or app.js file for node, do app.use(express.static(path.join(__dirname, 'whatevernameyouchoseforyourfrontendfiles')));
And after you serve the initial HTML files every time your server gets a request for a file it will know where to look.

Give value from node.js to its server's html

I need to give var into my html like server -> client
I'm not good at english and this situation is hard to explain so i will show you the code
html (index.html):
<script type="text/javascript">
console.log(tmp) //lol!
</script>
node.js:
fs.readFile('./index.html', (err, html) => {
if (err) {
response.statusCode = 404;
response.end(`error!`);
}
else
{
tmp="lol!"
response.write(html);
response.end();
}
});
server should response and give value to client same time. but it didn't work.
i don't want use external modules like express.js or ajax anything need to download things as it's possible
could you help me?
fs.readFile('./index.html', (err, html) => {
if (err) {
}
else
{
var tmp = new Object();
tmp.string = "hello world!"
var go = JSON.stringify(tmp)
res.write(`<div id="data"><div id="list" data-list='${go}'></div></div>`);
res.write(html);
res.end();
}
});
HTML:
var data = JSON.parse(document.getElementById("list").getAttribute("data-list"));
alert(data.string);
make a div element and set attribute, then write in response.

How to route to a page on a server using an onclick button?

<button type="submit" class="btn btn-success" onclick="on()">Force ON </button>
<script type="text/javascript">
function on(){req.url="/ledOn";}
</script>
This is my HTML button and i just need to route make it route to "ledOn" page in server.js file in order to perform some operations.
and this is the server.js file code.
var http = require('http');
var ejs = require('ejs');
var fs = require('fs');
var system = require('child_process').exec;
//var mraa = require('mraa');
var ledstatus = "off";
//var pin_2 = new mraa.Gpio(2);
//pin_2.dir(mraa.DIR_OUT);
http.createServer(function(req,res) {
res.writeHead(200, {'Content-Type': 'text/html'});
fs.readFile('index.html', 'utf-8', function(err, content) {
if (err) {
res.end('error occurred');
return;
}
var temp = 'some temp';
console.log("Request: " + req.url);
if(req.url === "/ledOn") {
//pin.write(0);
ledstatus = "on";
console.log("pin 7 on");
}
if(req.url === "/ledOff") {
//pin.write(1);
ledstatus = "off";
console.log("pin 7 off");
}
var renderedHtml = ejs.render(content, {temp: temp, ledstatus:ledstatus});
res.end(renderedHtml);
});
}).listen(8080);
** i wanna add more buttons with more routes to my html page to use it controlling my galileo board, so any help would be appreciated **

Form is timeouting on submitting without selected file in input type=file

Having a simple form as in the following js Fiddle http://jsfiddle.net/UdugW/ I am POSTing some form data to my node.js application (based on sails.js). This is one of the controller functions from product model:
image_upload: function(req, res) {
if (req.method.toLowerCase() == 'post') {
console.log("request: " + util.inspect(req.body));
if( req.files && req.files.product_image){
fs.readFile(req.files.product_image.path, function (err, data) {
var imageName = req.files.product_image.name;
if(!imageName){
console.log("There was an error with image upload : " + util.index(req.files.product_image));
res.redirect("/product/new_product");
res.end();
} else {
var newPath = UPLOAD_PATH + imageName;
/// write file to uploads/fullsize folder
fs.writeFile(newPath, data, function (err) {
res.writeHead(200, {'content-type': 'text/plain'});
res.end();
return;
});
}
});
}
}else if (req.body) {
console.log("product_name: " + product_name);
console.log("product_price: " + product_price);
console.log("product_description: " + product_description);
res.writeHead(200, {'content-type': 'text/plain'});
res.end();
}
else{
console.log("request err");
res.writeHead(500, {'content-type': 'text/plain'});
res.end();
}
},
I have a problem when I do not select an image for upload, then my POST request is timing out. Any ideas why this may happen ?
9/10 with node.js app, when something is timing out, chances are you forgot to close the socket (at least in my experience). and in your case it's no different :-)
here is the problem: you have this if-statement
if( req.files && req.files.product_image){
but the poor guy doesn't have a matching else-statement :-(
so if that condition is not true... well, nothing happens. execution basically just ends and the browser is left waiting... for ever.
just adding an else-statment with a res.end() inside of it and you should be good.
So something like this
if( req.files && req.files.product_image){
//all the stuff you already have for when it matches
}else{
console.log("No files were included in the post");
res.end();
}

How do I handle CSS with Node.js?

I'm trying to use just straight vanilla Node.js with no frameworks other than what is necessary for educational purposes. I currently have this setup:
var fs = require('fs'),
jade = require('jade');
function compile(dirPath, res) {
var filePath = __dirname + dirPath;
fs.readFile(filePath, 'utf8', function(err, fd) {
var fn = jade.compile(fd, { filename: filePath, pretty: true});
res.write(fn());
res.end();
});
}
exports.compile = compile;
Which is called when the requested page is asked for, like this:
var jadec = require('./jadecompile');
function start(res, postData) {
res.writeHead(200, {"Content-Type": "text/html"});
var cpage = '/staticpages/index.jade',
page = jadec.compile(cpage, res);
}
The page loads great and I get this as my view source:
<!DOCTYPE html>
<html>
<head>
<title>Hello!</title>
<link rel="text/css" href="assets/css/bootstrap.css">
</head>
<body>
<div class="hero-unit">
<p>Hello This Is A Test</p>
</div>
</body>
</html>
But the css doesn't work at all, I've been trying to google it but every answer seems to use express or something else, but I want to learn how to do this as vanilla as possible, so my question is, how can I handle the *.css so that the css is loaded properly, when I click on the href link in the view source, it loads my 404 page, rather than just the plain text of the css file. Thanks!
Feel free to view the repo at: https://github.com/Gacnt/Node-Tests
I managed to fix my problem by creating a function to handle static pages, such as .css or .js, like so:
var http = require('http'),
url = require('url'),
path = require('path');
fs = require('fs');
// ADDED THIS FUNCTION HERE -----------------------------------------------------
function handleStaticPages(pathName, res) {
var ext = path.extname(pathName);
switch(ext) {
case '.css':
res.writeHead(200, {"Content-Type": "text/css"});
fs.readFile('./' + pathName, 'utf8', function(err, fd) {
res.end(fd);
});
console.log('Routed for Cascading Style Sheet '+ pathName +' Successfully\n');
break;
case '.js':
res.writeHead(200, {"Content-Type": "text/javascript"});
fs.readFile('./' + pathName, 'utf8', function(err, fd) {
res.end(fd);
});
console.log('Routed for Javascript '+ pathName +' Successfully\n');
break;
}
}
// ADDED THIS FUNCTION HERE -----------------------------------------------------
function start(route, handle) {
function onRequest(req, res) {
var postData = "",
pathName = url.parse(req.url).pathname;
console.log('Request for ' + pathName + ' received.');
req.addListener('data', function(data) {
postData += data;
console.log('Received POST data chunk ' + postData + '.');
});
req.addListener('end', function() {
var pathext = path.extname(pathName);
if (pathext === '.js' || pathext === '.css') {
handleStaticPages(pathName, res);
} else {
console.log('--> Routing only the view page');
route(handle, pathName, res, postData);
}
});
}
http.createServer(onRequest).listen(4000);
console.log('Server is now listening at: http://127.0.0.1:4000 .');
}
exports.start = start;
In order to handle .css and other static files, there needs to be a file stream in place. Rather than using a switch statement you can just use the following.
var stream = fs.createReadStream(path); //create the file stream
stream.pipe(res); //transfer the file

Categories

Resources