I'm trying to pick up a file from a form and save it to myself on disk in any folder. I would like to do it by sockets, but I do not know how to handle it. Can someone help me?
This is my code:
main.js
var http = require('http');
var fs = require('fs');
var io = require('socket.io');
var path = require('path');
var server = http.createServer(function (req, res) {
fs.readFile(__dirname + '/index.html', function (err, data) {
if (err) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write("Not Found");
res.end();
} else {
res.write(data, 'utf8');
res.end();
}
});
}).listen(8000);
var listener = io.listen(server);
listener.sockets.on('connection', function (socket) {
console.log("Connected");
socket.on('disconnect', function () {
console.log("Disconnect");
});
socket.on('form.message', function (data) {
// here to handle the file ??
socket.emit('new.message', {msg: data});
});
});
index.html(client)
<script>
$(function () {
var socket = io.connect();
var $messageForm = $('#messageForm');
var $file = $('#file');
var $outputFile = $('#outputFile');
var obj = {
file: $file.val(),
};
e.preventDefault();
console.log(obj);
socket.emit('form.message', obj);
$file.val('');
socket.on('new.message', function (data) {
$outputFile.append('<div class="well">' + data.msg.file + '</div>');
});
});
</script>
Related
I'm new programmer to node.js. I trying to create vanilla server in node.js. In my client, I used ES6 modules. when I start my server and search for http://localhost:3000/ in my browser, HTML and CSS loaded but for javascript have this error:
I have four javascript modules for client side and in HTML I use this code for load javascript moduls:
<script type="module" src="js/controller.js" async></script>
My server code :
const http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = 3000;
const server = http.createServer();
server.on('request', (req, res) => {
let routes = {
'GET': {
'/': indexHtml,
}
}
console.log(req.url)
let handler = routes[req.method][req.url];
handler = handler || readFile;
handler(req, res);
})
server.listen(PORT, () => {
console.log(`Listening on port ${PORT}...`)
});
function indexHtml(req, res) {
readFile({ url: '/index.html' }, res);
}
function readFile(req, res) {
var filePath = path.join(__dirname, '../client/', req.url);
// console.log(filePath)
fs.readFile(filePath, (error, data) => {
if (error) {
res.writeHead(404);
res.write('Not found error 404');
res.end()
} else {
res.writeHead(200);
res.write(data);
res.end();
}
})
}
How can I solve this error and serve javascript modules, Thanks a lot for your help.
With comment #derpirscher, I change my reader function with this code :
function readFile(req, res) {
var filePath = path.join(__dirname, '../client/', req.url);
fs.readFile(filePath, (error, data) => {
if (error) {
res.setHeader('Content-Type', 'text/html');
res.writeHead(404);
res.write('Not found error 404');
res.end()
} else {
const url = req.url === '/' ? '/index.html' : req.url;
if (req.url.includes('js')) res.setHeader('Content-Type', 'application/javascript');
if (req.url.includes('css')) res.setHeader('Content-Type', 'text/css');
if (req.url.includes('html')) res.setHeader('Content-Type', 'text/html');
res.writeHead(200);
res.write(data);
res.end();
}
})
}
I cant understand how and where to use response.end(). i get it working when loading only single response but when i try to load (say) two html files (index and form in my case) , the server does not load anything.
if i put res.end() after loading the index html it works but server closes.
var http = require('http');
var formidable = require('formidable');
var url=require('url');
var path=require('path');
var fs=require('fs');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
filepath=path.join(__dirname,'index.html');
fs.readFile(filepath,null,function(err,data){
if(err){
res.writeHead(404);
res.write(err+" Error");
}
else{
res.write(data);
}
res.end();
});
if (req.url == '/fileupload') {
var form = new formidable.IncomingForm();
form.parse(req, function () {
res.write('File uploaded');
res.end();
});
} else {
var q=url.parse(req.url,true);
var filename=path.join(__dirname,q.pathname);
console.log(filename);
fs.readFile(filename,function(err,data){
if (err) {
res.writeHead(404);
res.write(err+"404 Not Found");
}
else{
res.write(data);
}
res.end();
})
}
}).listen(8080);
Other tips on improving code is much appreciated :)
var http = require('http');
var formidable = require('formidable');
var url = require('url');
var path = require('path');
var fs = require('fs');
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/html' });
if (req.url == '/fileupload') {
var form = new formidable.IncomingForm();
form.parse(req, function () {
res.write('File uploaded');
res.end();
});
} else if (req.url.length > 1) {
var q = url.parse(req.url, true);
var filename = path.join(__dirname, q.pathname);
console.log(filename);
fs.readFile(filename, function (err, data) {
if (err) {
res.writeHead(404);
res.write(err + "404 Not Found");
}
else {
res.write(data);
}
res.end();
})
} else {
filepath = path.join(__dirname, 'index.html');
fs.readFile(filepath, null, function (err, data) {
if (err) {
res.writeHead(404);
res.write(err + " Error");
}
else {
res.write(data);
}
res.end();
});
}
}).listen(8080);
I'm fairly new to nodejs, and in wanting to keep the code neat and clean, I tried to extract a function to a different file, and then require it from my main app.
I'm facing a problem that this function includes socket-io data streaming and it uses the http module that uses my express app
This is the main app, and I want to move the content of getDetails to a seperate file:
const express = require('express');
const app = express();
const spawn = require('child_process').spawn;
const execFile = require('child_process').execFile;
const server = require('http').Server(app);
const io = require('socket.io')(server);
// Set router
const router = express.Router();
// fix body of requests
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
router.get('/getDetails', (req, res) => {
const qry = req.query;
if (qry.func === 'tail') {
const tail = spawn('ssh', ['root#' + qry.srv, qry.script, qry.func, qry.serv]);
io.on('connection', function (socket) {
tail.stdout.on('data', function (data) {
socket.emit('newLine', {line: data.toString('utf8').replace(/\n/g, '<br>')});
});
tail.on('close', (code) => {
console.log('child process exited with code', code);
});
tail.stderr.on('data', (data) => {
console.log('There are some errors:', data.toString('utf8'));
socket.emit('newLine', {line: data.toString('utf8')});
});
});
res.sendStatus(200);
}
else {
execFile('ssh', ['root#' + qry.srv, qry.script, qry.func, qry.serv], {timeout: 5000}, (error, stdout, stderr) => {
if (error) {
console.error('stderr', error);
return res.status(500).send({stderr: stderr, error: error});
}
return res.status(200).send({stdout: stdout.toString('utf8')});
});
}
});
app.use('/', router);
server.listen(port, function () {
console.log('The magic happens on localhost:' + port);
});
Now I can module.exports everything on my seperate file but do I need to also require express, and http again?
And should I move the server.listen to the seperate file?
server.js
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const route = require('./route');
// fix body of requests
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json())
app.set('socketio', io);
app.use('/',route);
server.listen(port, function () {
console.log('The magic happens on localhost:' + port);
});
route.js
const express = require('express');
const router = express.Router();
const Controller = require('./controller');
router.post('/register',Controller.getDetails);
module.exports=router;
controller.js
const spawn = require('child_process').spawn;
const execFile = require('child_process').execFile;
const controller = {
getDetails : (req,res)=>{
// now use socket.io in your controller file
var io = req.app.get('socketio');
const qry = req.query;
if (qry.func === 'tail') {
const tail = spawn('ssh', ['root#' + qry.srv, qry.script, qry.func, qry.serv]);
io.on('connection', function (socket) {
tail.stdout.on('data', function (data) {
socket.emit('newLine', {line: data.toString('utf8').replace(/\n/g, '<br>')});
});
tail.on('close', (code) => {
console.log('child process exited with code', code);
});
tail.stderr.on('data', (data) => {
console.log('There are some errors:', data.toString('utf8'));
socket.emit('newLine', {line: data.toString('utf8')});
});
});
res.sendStatus(200);
}
else {
execFile('ssh', ['root#' + qry.srv, qry.script, qry.func, qry.serv], {timeout: 5000}, (error, stdout, stderr) => {
if (error) {
console.error('stderr', error);
return res.status(500).send({stderr: stderr, error: error});
}
return res.status(200).send({stdout: stdout.toString('utf8')});
});
}
}
}
module.exports=controller;
Hello I am new in nodeJS, I am trying to broadcast message when any new request arrive.
I am trying ajax calling and send ttype variable and broadcast to all browsers but My problem is when I request arrive
socket.emit('date', {'date': ttype});
not working. but when I checked it on my nodeJs console it's show tyype and it's value. here is my code
var http = require('http');
var url = require('url');
var fs = require('fs');
var server;
var ttype = "";
server = http.createServer(function(req, res){
// your normal server code
var path = url.parse(req.url).pathname;
var queryObject = url.parse(req.url,true).query;
ttype = queryObject.type;
switch (path){
case '/':
fs.readFile(__dirname + path + "test.html", function(err, data){
if (err){
console.log('error');
//return send404(res);
}
res.writeHead(200, {'Content-Type': path == 'json.js' ? 'text/javascript' : 'text/html'});
res.write(data, 'utf8');
res.end();
sendMessage(ttype);
});
break;
case '/test.html':
fs.readFile(__dirname + path, function(err, data){
if (err){
return send404(res);
}
res.writeHead(200, {'Content-Type': path == 'json.js' ? 'text/javascript' : 'text/html'});
res.write(data, 'utf8');
res.end();
});
break;
default: send404(res);
}
}),
send404 = function(res){
res.writeHead(404);
res.write('404');
res.end();
};
server.listen(8076);
sendMessage = function(ttype){
var iio = require('socket.io').listen(server);
iio.sockets.on('connection', function(socket){
socket.emit('date', {'date': ttype});
console.log('in side connection');
});
}
// use socket.io
var io = require('socket.io').listen(server);
// define interactions with client
io.sockets.on('connection', function(socket,data){
socket.emit('date', {'date': ttype});
setInterval(function(){
//socket.emit('date', {'date': new Date()});
}, 5000);
//recieve client data
socket.on('client_data', function(data){
process.stdout.write(data.letter);
});
});
So if you'd like to let all browsers know that there is a new request by sending them ttype. All you would have to do is change your sendMessage function to:
sendMessage = function(ttype){
io.emit('date', {'date': ttype});
console.log('in side connection');
}
I'm working on a Node.js app, using http and httpdispatcher to handle web server requests. I have the following code:
var app = require('http').createServer(handler),
sys = require('util'),
exec = require('child_process').exec,
io = require('socket.io').listen(app),
fs = require('fs'),
dispatcher = require('httpdispatcher');
app.listen(61337);
dispatcher.setStatic('assets');
function puts(error, stdout, stderr) { sys.puts(stdout) }
function handler (request, response) {
dispatcher.dispatch(request, response);
}
dispatcher.onGet("/", function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
fs.readFile('./assets/index.html', 'utf8', function (err,data) {
res.end(data);
});
});
dispatcher.onGet("/api/update", function(req, res) {
exec("sh /path/to/update.sh &", puts);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('1');
});
io.sockets.on('connection', function (socket) {
/** Socket.io coming soon */
});
I get the following errors.
path.js:360
throw new TypeError('Arguments to path.join must be strings');
TypeError: Arguments to path.join must be strings
at path.js:360:15
at Array.filter (native)
at Object.exports.join (path.js:358:36)
at HttpDispatcher.staticListener (***/httpdispatcher.js:81:39)
at ***/httpdispatcher.js:132:3
at HttpChain.next (***/httpdispatcher.js:125:9)
at doDispatch (***/httpdispatcher.js:58:13)
at HttpDispatcher.dispatch (***/httpdispatcher.js:74:14)
at Server.handler (***/app-server.js:19:13)
at Server.<anonymous> (***/socket.io/node_modules/engine.io/lib/server.js:369:22)
The Server.handler (***/app-server.js:19:13) line is dispatcher.dispatch(request, response); in the handler function.. so I'm not sure why it's not sending strings?
I went from using httpdispatcher to express
Here is my working example:
var express = require('express'),
app = express(),
http = require('http').createServer(app).listen(61337),
sys = require('util'),
exec = require('child_process').exec,
io = require('socket.io')(http),
fs = require('fs');
app.use('/assets', express.static('assets'));
function puts(error, stdout, stderr) { sys.puts(stdout) }
app.get("/", function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
fs.readFile('./assets/index.html', 'utf8', function (err,data) {
res.end(data);
});
});
app.get("/api/update", function(req, res) {
exec("sh /path/to/update.sh &", puts);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('1');
});
io.sockets.on('connection', function (socket) {
});