js application. Need help to resolve this issue.
I have app.js which is node, calls index.html. The index.html intern calls main.js function clicked. It works fine when I have funtion 'clicked()' embeded inside index.html using script tag. But does not work if function clicked is in a seperate js file. I think this is something regarding to node.js but unable to figure out. Please find my code below.
app.js
var http = require('http');
var fs = require('fs');
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
var request = require('request');
request('http://localhost:8000/test', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
});
var server = http.createServer(function(req,res){
console.log('Request was made:' + req.url);
res.writeHead(200,{'content-Type': 'text/html'});
var myReadStream = fs.createReadStream(__dirname + '/index.html','utf8');
myReadStream.pipe(res);
});
server.listen(3000,'127.0.0.1');
console.log('Listening on port 3000');
index.html
<!DOCTYPE html>
<html>
<head>
<title> Login</title>
<script type="text/javascript" src="main.js"></script>
<center>
<h1> Login </h1>
</center>
</head>
<body>
<center>
<input type="text" id="username" placeholder="UserName"></br>
<input type="password" id="password" placeholder="PassWord"></br>
<input type="button" value="Login" onclick="clicked()">
</center>
</body>
</html>
main.js
function clicked() {
var user = document.getElementById('username');
var pass = document.getElementById('password');
var checkuser = "test";
var checkpass = "123"
if (user.value == checkuser) {
if (pass.value == checkpass) {
window.alert("You are logged in as "+ "'"+user.value+"'");
open("http://www.yahoo.com");
}
else
window.alert("Incorrect username or Password");
}
else
window.alert("Incorrect username or Password");
}
ScreenShot of the Error:
This is because the Node.js server does not serve main.js correctly -- According to the browser's "Resources" panel, main.js is available, but its path is not /main.js.
Low level Node.js server code and Express framework code co-exist, which is not a good idea.
To solve the problem with low level Node.js code:
var server = http.createServer(function(req,res){
console.log('Request was made:' + req.url);
if (req.url === '/main.js') {
res.writeHead(200,{'content-Type': 'application/javascript'});
var jsReadStream = fs.createReadStream(__dirname + '/main.js','utf8');
jsReadStream.pipe(res);
return;
}
res.writeHead(200,{'content-Type': 'text/html'});
var myReadStream = fs.createReadStream(__dirname + '/index.html','utf8');
myReadStream.pipe(res);
});
To solve the problem with Express framework:
var http = require('http');
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.get('/main.js', function(req, res) {
res.sendFile(path.join(__dirname + '/main.js')); // where main.js located.
});
app.set('port', 3000);
var server = http.createServer(app);
server.listen(port);
You are using both http and express, which is probably unnecessary. I would serve static files with app.use(express.static('public')), per the docs. Then you can serve the index with
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/index.html'))
});
And start the server with app.listen(3000);
Related
I am very new to node.js and have been googling for a solution to the problem stated in my question title above.
Basically I am building a simple web api that allows users to upload their files and then query them individually after that. So I am trying to figure out how to display the list of files in the server directory so instead of them remembering the exact file name, they can pick it from the list.
Here's my full html code project/public/index.html (EDIT - after answered by Oorja)
<!DOCTYPE html>
<html>
<head>
<script src="./node_modules/jquery/dist/jquery.min.js"></script>
</head>
<style>
.dropdown-content {
display: none;
position: absolute;
background-color: #f6f6f6;
min-width: 230px;
overflow: auto;
border: 1px solid #ddd;
z-index: 1;
}
.show {display:block;}
</style>
<body>
<h1>api service</h1>
<br>
<div id="upload_form">
<h3>Upload images</h3>
<form action="/api/uploadImages" method="post" enctype="multipart/form-data">
<input type="file" name="image" multiple="multiple"><br><br>
<input type="submit" value="Upload">
</form>
</div>
<div id="query_images">
<h3>Query images</h3>
<form action="/api/queryImages" method="get" enctype="text/plain">
<input type="text" name="image_name"><br><br>
<input type="submit" value="Query">
</form>
</div>
<div class="dropdown">
<button onclick="show_list()" class="dropbtn">Images</button>
<div id="image_list" class="dropdown-content">
<input type="text" placeholder="Search for your images..." id="userInput">
</div>
</div>
<script>
function show_list() {
var image_list = document.getElementById("image_list");
$.getJSON('http://localhost:8080/list-files', function(data) {
data.forEach(function(file) {
$(image_list).append($('' + file + ''));
})
});
}
</script>
</body>
</html>
And below is the javascript full code project/server.js (EDIT - after answered by Oorja)
var express = require('express'),
multer = require('multer'),
bodyParser = require('body-parser'),
path = require('path')
fs = require('fs');
var app = express();
var imageStorage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './uploaded_files');
},
filename: function(req, file, callback) {
callback(null, file.fieldname + '_' + Date.now() + '_' + file.originalname);
}
});
var upload = multer({
storage: imageStorage,
fileFilter: function(req, file, callback) {
console.log('Checking file extension...');
var extension = path.extname(file.originalname);
if (extension == '.jpg' || extension == '.png' || extension == '.jpeg') {
console.log('Extension looks good!');
callback(null, true);
} else {
callback('Please upload images only!', false);
}
}
}).array('image');
app.use(bodyParser.json());
app.use('/uploaded_files', express.static('./upload_files'));
// define http methods handlers
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname, 'public', 'index.html'))
});
app.get('/list-files', function(req, res) {
var files = fs.readdirSync('./uploaded_files');
res.json(files);
})
app.get('/api/queryImages', function(req, res) {
var imageName = req.query.image_name
console.log(imageName);
res.sendFile(path.join(__dirname, 'uploaded_files', imageName));
});
app.post('/api/uploadImages', function(req, res) {
upload(req, res, function(err) {
if (err) {
console.log(err);
return res.end('Something went wrong!');
}
console.log('Upload successful!')
res.send('Successfully uploaded images!');
});
});
app.listen(port=8080, function(a) {
console.log('Listening to port ' + port);
});
The javascript works /list-files as I can see the list of files in my console or if I go to /list-files url, however, I cannot figure out how to send the output to front end - I don't know how to connect them - so then when I click on the button under div class="dropdown" they will appear as a list <a> element.
Could someone please point me in the right direction or even better, give me an example?
Thank you in advance!
EDIT
Output of files from the javascript above /list-files is as below
[ '.DS_Store',
'Screen Shot 2018-06-02 at 2.15.10 pm.png',
'aaa.png',
'bbb.png',
'ccc.png',
'ddd.png',
'eee.png' ]
Also, to clarify, I am using Express framework to build this web api.
Once you have the list of files ready, make an API end-point for it. Say, /get-files. Assuming you're using express as a node.js server, you can do this -
const express = require('express');
const fs = require('fs');
const app = express();
// Makes your upload_files directory public. Don't use this in a real app.
// Create a separate route to serve file data. This is just for brevity of code.
app.use('/upload_files', express.static('./upload_files'))
app.get('/get-files', (req, res) => {
// your logic of getting file names
const files = fs.readdirSync('./upload_files');
res.json(files);
});
app.listen(3000); // start a server at localhost:3000
Now, on your frontend, you can open an XHR GET request to fetch the name of files you have on the node.js server like so -
function show_list() {
var image_list= document.getElementById('image_list');
// Assuming you have jQuery as well...
$.getJSON('http://localhost:3000/get-files', function (data) {
data.forEach(file => {
// Do something with the file name
$(image_list).append($('' + file + ''));
})
});
}
You can read more about Express here.
You can also do what Tamas has done with Server-side templating. It will send the data along with the HTML file but I doubt if that is what you asked for.
You should try a template engine like EJS.
Example usage if you use express:
EJS uses the views folder in root for html files default, so create it and put your index.html there.
0. Install EJS: npm install ejs
1. Include EJS in express: app.set('view engine', 'ejs');
2. Add to your route: res.render('index', {files: files});
3. Get it in HTML, modify your index.html (put it where you need):
<% for (var i = 0; i < files.length; i++) { %>
<%= files[i] %>
<% }; %>
Or if you need it as a JS variable use:
<script> var files = <%- JSON.stringify(files) %>; </script>
More information
For some reason, I have attached my css file to my html file. And then i open the html file using express in node js. However, the css file does not open when i run the webserver through node js. I thought since the css file is included in html that it should run??
html
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css" media="screen" />
</head>
<body>
<h1>Reading in Value</h1>
<form action="/" method="post" >
<br/>
<label>Enter a UDP command in hex</label>
<br/><br/>
<input type="number" name="number" id="number">
<br/><br/>
<input type="submit" value="Submit" name="submit">
<meta name="viewport" content="width=device-width, initial-scale=1">
</form>
</body>
</html>
node js
//Sending UDP message to TFTP server
//dgram modeule to create UDP socket
var express= require('express')
var fs= require('fs')
var util = require('util')
var dgram= require('dgram')
var client= dgram.createSocket('udp4')
var bodyParser = require('body-parser')
var app = express()
var app2= express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
//Reading in the html gile
app.get('/', function(req, res){
var html = fs.readFileSync('index2.html');
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(html);
});
//Sends user command utp
app.post('/', function(req, res){
//Define the host and port values
var HOST= '192.168.0.172';
var PORT= 69;
//buffer with hex commands
var message = new Buffer(req.body.number, 'hex');
//Sends packets to TFTP
client.send(message, 0, message.length, PORT, HOST, function (err, bytes) {
if (err) {
throw err;
}
res.send('UDP message sent to ' + HOST +':'+ PORT);
});
});
//CREATES ANOTHER PORT
app2.get('/', function(req, res){
client.on('message', function (message) {
res.send('received a message: ' + message);
});
});
app.listen(3000, "192.168.0.136");
app2.listen(8000, "192.168.0.136");
console.log('Listening at 192.168.0.172:3000 and Recieve message will be on 192.168.0.172:8000')
<link rel="stylesheet" type="text/css" href="style.css" media="screen" /> tells the browser to ask (with GET) the server for the CSS at /style.css.
Look at your server code. You've told it what to do with GET / (app.get('/', function(req, res){ etc), and you've told it what to do for POST /, but you haven't told it what to do for GET /style.css.
The Express manual covers this.
Wherever you're serving your files from, you need to set in the express config like this:
app.use(express.static('public'));
This would work if you're static files were being stored in a folder called public. Please see this link for more documentation: http://expressjs.com/en/starter/static-files.html
First of all: I am a beginner at nodeJS!
My Problem is that i have an html-file, which is complex, and i want to write an individual response in it. For example
index.js
var express = require('express');
var app = express();
var server = app.listen(3000, function () {
console.log('Listening at port 3000');
});
app.use(express.static('public'));
app.get('/', function(req, res){
res.sendFile(__dirname + 'index.html');
//
// what to write here when i want to modify the index.html before sending?
//
});
index.html
<!DOCTYPE HTML>
<html>
<div id="writehere">
<!--I would like to modify the page here-->
</div>
</html>
I hope you can help me and understood my question!
I'm a real noob when it comes to nodejs, jsut started this a couple of days ago. I can't figure out why my js and css files aren't applied. There are no 404 errors so that doesn't seem to be it. I'm trying to read the files using express. I'm getting these console errors in dev tools:
GamblerScript.js:1 Uncaught SyntaxError: Unexpected token <
jquery-2.2.0.min.js:1 Uncaught SyntaxError: Unexpected token <
localhost/:5 Resource interpreted as Stylesheet but transferred with MIME type text/html: "http://localhost:8080/css/Stylesheet.css".
(index):9 Uncaught ReferenceError: Run is not defined
Is there any one who can see what i'm doing wrong?
var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.sendfile('/index.html');
});
app.use(express.static(__dirname + '/public'));
fs.readFile('./index.html', function (err, html) {
if (err) {
throw err;
}
http.createServer(function(request, response) {
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
}).listen(8080);
});
<html lang="en">
<head>
<title>Dices</title>
<link rel="stylesheet" href="/css/Stylesheet.css">
<script src="/js/GamblerScript.js"></script>
<script src="/js/jquery-2.2.0.min.js"></script>
</head>
<body onload="Run();">
<div id="spinboxcontainer">
<div class="spinbox">
<span class="spinspan">Dices</span>
</div>
<div id="container">
<div id="spinner1" class="spinner">
<div id="D1.1" class="one">1</div>
<div id="D1.2" class="two">2</div>
<div id="D1.3" class="three">3</div>
<div id="D1.4" class="four">4</div>
<div id="D1.5" class="five">5</div>
<div id="D1.6" class="six">6</div>
</div>
</div>
<div id=container2>
<div id="spinner2" class="spinner">
<div id="D2.1" class="one">6</div>
<div id="D2.2" class="two">5</div>
<div id="D2.3" class="three">4</div>
<div id="D2.4" class="four">3</div>
<div id="D2.5" class="five">2</div>
<div id="D2.6" class="six">1</div>
</div>
</div>
</div>
</body>
</html>
function Run(){
alert('Welcome');
var clickNumber = 1;
document.getElementById('spinner1').addEventListener("click", function(){
alert('Your click is number ' + clickNumber + '!');
document.body.className -= ' WhiteBackground';
clickNumber = clickNumber + 1;
});
document.getElementById('spinner2').addEventListener("click", function(){
alert('Your click is number ' + clickNumber + '!');
document.body.className += ' WhiteBackground';
clickNumber = clickNumber + 1;
});
};
You messing up different approaches. If you use express there is no need to http.createServer and manually read your static files with fs.readFile. For simple static server just simplify your main file like this
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.listen(8080, function() {console.log('server listening on port 8080...')})
The error you've got is because whenever the browser asks server for script files like jquery and GamblerScript your custom http server sends your index.html file back and browser tryes execute it like javascript.
There are a few things you are doing wrong.
In the bottom half of your code, in the callback passed to fs.readFile(), you create a Node server to handle all requests. The emphasized words are key here: you are creating a server using only Node's built-in features, which you shouldn't need to do when using Express; and the server handles all requests, not just those to your index.html file, as I think you intended. So, when the requests for your CSS and JavaScript come in, you are sending index.html as a response. This won't do.
Luckily, the solution is simpler than the original problem. Just do this:
'use strict';
const path = require('path');
const express = require('express');
const app = express();
// This just lets you set an alternate port with an environment variable,
// if you want.
const PORT = process.env.PORT || 8080;
// Set your static folder before any request handlers.
app.use(express.static(path.resolve(__dirname, 'public')));
// Handles request to root only.
app.get('/', (req, res) => {
// If you needed to modify the status code and content type, you would do so
// using the Express API, like so. However, this isn't necessary here; Express
// handles this automatically.
res.status(200);
res.type('text/html');
// Use sendFile(absPath) rather than sendfile(path), which is deprecated.
res.sendFile(path.resolve(__dirname, 'index.html'));
});
// Call the listen() method on your app rather than using Node's http module.
app.listen(PORT, (err) => {
if (err) throw err;
else console.log(`Listening on port ${PORT}`);
});
I made an online multiplayer game. I works perfectly when I run it with node.js command prompt on localhost:3000. But when I try to run it on the website it is not doing what my app.js file says it to do. my questions are;
How can I make my node.js project run on my website rather than on localhost?
What will the port be instead of 3000?
Can I do this by uploading some file into my website via ftp?
Here is my app.js file
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);
var usernumm = 0;
var usernum1 = [];
app.use(express.static(__dirname + '/public'));
server.listen(3000);
app.get('/', function(req, res){
res.sendfile(__dirname + '/index.html');
});
io.sockets.on('connection', function(socket){
var endpoint = socket.manager.handshaken[socket.id].address;
console.log('***New connection from ' + endpoint.address + ':' + endpoint.port);
usernumm++;
io.sockets.emit('usernum', usernumm);
usernum1[usernumm] = endpoint.port;
console.log('usernum'+usernumm+'geldi'+findusernum());
socket.on('button1socket', function(){
io.sockets.emit('button1f', findusernum() );
console.log('user '+findusernum()+' pressed a button');
});
socket.on('buttonclickable', function(){
io.sockets.emit('buttonclickable1', findusernum() );
});
socket.on('disconnect', function () {
usernumm--;
io.sockets.emit('usernum', usernumm);
//sockets[usernum] = socket.port;
console.log('***Client disconnected');
});
//finds number of online users
function findusernum(){
for(var i = 0; i<9;i++){
if(usernum1[i] == endpoint.port){return i;}else{}
}
}
});
try:
var express = require('express');
var app = express();
var httpServer = require('http').Server(app);
var socketServer = require('socket.io')(httpServer);
var ip = 'iphere';
var port = 80;
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.sendfile(__dirname + '/index.html');
});
socketServer.on('connection', function(socket){
console.log("A Client has connected.");
socket.on('disconnect', function(){
console.log("A Client has disconnected.");
});
});
httpServer.listen(port, ip, function(){
console.log("Listening to "+ip+":"+port);
});
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
<script type="text/javascript" src="http://ip:port/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket;
try{
socket = io("http://ip:port/", {'forceNew':true });
socket.on('connect', function(error){
if(error){
}
});
}catch(e){
}
</script>
</head>
<body>
</body>
</html>
after you have specified your ip and port
port forward the port you have specified to live your website/game using your router
then you can visit it with http://yourpublicip:port/
if its port 80 then visit the page without the port.