Localhost test: can't get resource using http://localhost:8888 - node.js

For test purposes I run Apache local web server and I'm setting up a node.js app listening on port 8888 serving as image preprocessor, but unfortunately I'm experiencing problems as described below.
The node app.js is running in the web root directory:
'use strict';
let express= require('express')
,multer = require('multer')
,upload = multer()
,app = express()
//Import imgProcessor module which we would implement later
,imgProc = require('./imgProcessor');
app.get ('/', (req, res, next)=>{
res.sendFile(__dirname+'/appmain.html');
});
app.post('/uploadImg', upload.array('pics'),
(req, res, next)=>{
//Call the convertImgs method and pass the image files as its argument
imgProc.convertImgs(req.files).then(
(imageStringArray)=>{
//After all image processing finished, send the base64 image string to client
res.json(imageStringArray)})});
app.listen(8888, ()=>{
console.log('Hosted on Port 8888')});
The appmain.html page resides in the same web root directory:
<html>
<head>
<title>Upload Image Demo</title>
<link rel="shortcut icon" href="">
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="node_modules/materialize-css/dist/js/materialize.min.js"></script>
<link rel="stylesheet" href="node_modules/materialize-css/dist/css/materialize.min.css">
</head>
<body class="container">
<div class="row">
<form id="form1" class="col m4 offset-m4" action="/uploadImg" enctype="multipart/form-data" method="post">
<div class="file-field input-field">
<div class="btn">
<span>File</span>
<input type="file" multiple="" accept="image/jpeg,png" name="pics">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="Upload one or more files">
</div>
</div>
<div class="input-field">
<button type="submit" class="waves-effect waves-light btn">Submit</button>
</div>
<div class="progress" style="display:none">
<div class="indeterminate"></div>
</div>
</form>
</div>
<div class="row img-preview"></div>
<script>
$(function(){
$('#form1').on('submit', function(event){
event.preventDefault();
var data = new FormData(this);
$.each(
$('input[name="pics"]')[0].files,
function(i, file){
data.append('file-'+i, file);
});
$('.progress').css({
display:'block'
});
$.ajax({
type:'POST',
url: $(this).attr('action'),
data:data,
cache:false,
contentType: false,
processData: false,
success:function(data){
for(var i=0;i<data.length;i++){
var template =
'<div class="col m4">
<div class="card">
<div class="card-image">
<img src="'
+ data[i]
+ '"></div></div></div>';
$('.img-preview').append(template);
}
$('.progress').css({
display:'none'
});
},
error: function(err){
$('.progress').css({
display:'none'
});
}
});
})
})
</script>
</body>
</html>
When I use the URL http://localhost:8888 in the browser the html page is loaded (i.e. I can see the buttons and input fields of the form) but the resources requested in the <script> (ex.: node_modules/jquery/dist/jquery.min.js or node_modules/materialize-css/dist/js/materialize.min.js) are not loaded. By the same way the page can't benefit from the unloaded CSS stylesheet.
As opposite, if I try to use the URL http://localhost/appmain.html the page is loaded as expected (I mean: with the correct resources and CSS).
It seems that my Apache Web Server can't serve resources when handling the port number inside the URL. How can I resolve this?
EDIT
Just to simplify: let'say the node app2.js is listening on port 8888 and it has just a method (get) that send to the client the 'Hello World!' page app2main.html. No files to serve. The app2main.html page need only to load a couple of Javascript script and a CSS stylesheet.
app2.js
'use strict';
let express= require('express')
,app = express();
app.get ('/', (req, res, next)=>{
res.sendFile(__dirname+'/app2main.html');
});
app.listen(8888, ()=>{
console.log('Hosted on Port 8888')});
app2main.html
<html>
<head>
<title>Upload Image Demo</title>
<link rel="shortcut icon" href="">
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script
src="node_modules/materialize-css/dist/js/materialize.min.js"></script>
<link rel="stylesheet"
href="node_modules/materialize-css/dist/css/materialize.min.css">
</head>
<body class="container">
<h2> Hello World! </h2>
</body>
</html>
When accessing the URL http://localhost:8888 the 'Hello World!' message appears, but I get the following error (visibile by inspecting the page):
http://localhost:8888/node_modules/jquery/dist/jquery.min.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8888/node_modules/materialize-css/dist/js/materialize.min.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8888/node_modules/materialize-css/dist/css/materialize.min.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8888/node_modules/materialize-css/dist/css/materialize.min.css Failed to load resource: the server responded with a status of 404 (Not Found)
Instead I get no error (and the expected style) when accessing the URL http://localhost/app2main.html

As discussed in comments, you should use express.static to serve static content in node.js app. In your case, your static content lies in node_modules directory itself. You can try the following code to load all resources,
e.g. http://localhost:8888/node_modules/jquery/dist/jquery.min.js
app.use('/node_modules', express.static('node_modules'));
Also, you mentioned that when you access http://localhost/app2main.html, then it worked without express.static, because apache web server to serve static files similar to express.static in node.js. That's why
http://localhost/node_modules/jquery/dist/jquery.min.js was working.
Hope it clears your doubt.

Related

Cannot load css file in ejs file

I am using an ejs file which is supposed to include a css file for styling, but the css file wouldn't load. Can someone help me resolve the issue. The server only loads the html view, but not css, despite using express.static() to serve the static files.
signup.ejs:
<!DOCTYPE html>
<html>
<head>
<title>Hostel</title>
<link rel="stylesheet" type="text/css" href="../assets/css/signup.css">
<link href="https://fonts.googleapis.com/css2?family=Jost:wght#500&display=swap" rel="stylesheet">
</head>
<body>
<div class="main">
<input type="checkbox" id="chk" aria-hidden="true">
<div class="signup">
<form>
<label for="chk" aria-hidden="true">Sign up</label>
<input type="text" name="txt" placeholder="User name" required="">
<input type="email" name="email" placeholder="Email" required="">
<input type="password" name="pswd" placeholder="Password" required="">
<button>Sign up</button>
</form>
</div>
<div class="login">
<form>
<label for="chk" aria-hidden="true">Login</label>
<input type="email" name="email" placeholder="Email" required="">
<input type="password" name="pswd" placeholder="Password" required="">
<button>Login</button>
</form>
</div>
</div>
</body>
</html>
app.js:
const express=require("express");
const connectDB = require("./db");
const app=express();
const path=require("path");
const userRouter=require("./routes/users");
app.use(express.json());
const port=process.env.PORT || 3000;
connectDB();
app.set('views', path.join(__dirname, '/views'));
app.set("view engine", "ejs");
app.use('/css', express.static(path.resolve(__dirname, "assets/css")));
app.use('/js', express.static(path.resolve(__dirname, "assets/js")));
app.use("/",(req,res,next)=>{
res.render("signup");
});
app.use("/users",userRouter);
app.listen(port,()=>{
console.log(`Server running on port ${port}`);
});
Folder Structure:
server
|
|->assets/css/signup.css
|->views/signup.ejs
|->app.js
Thank you in advance
Problem
The URLs in your HTML page don't match the express.static() middleware you have.
So, for example, when you have this:
<link rel="stylesheet" type="text/css" href="../assets/css/signup.css">
That's going to combine the path and domain of of the page URL to formulate a request to your server for something like:
/assets/css/signup.css
But, you don't have a route that matches that. You have this:
app.use('/css', express.static(path.resolve(__dirname, "assets/css")));
But, that requires a path that starts with /css and you have no route that starts with /assets.
Solution
So, drop the reference in the HTML page to /assets. That's an internal (to your server) location that the HTML page doesn't need to know anything about. In fact, you can technically change that on your server without breaking or changing the web page.
So, change your HTML tag to this:
<link rel="stylesheet" type="text/css" href="/css/signup.css">
This is an absolute path URL and will send a request for:
/css/signup.css
That will match your route here:
app.use('/css', express.static(path.resolve(__dirname, "assets/css")));
The /css part of the URL will match the app.use('/css', ...) route and after removing the /css part from the path, it will then look for the remaining page of the URL signup.css in the path.resolve(__dirname, "assets/css") directory.

Node.js (express framework): Post method not working

I am able to run the Get method and HTML form also visible on browser using Get method but when I am clicking on submit button nothing is happening, no error nothing. it shows the same HTML form page.
HTML code:
<!DOCTYPE html>enter code here
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Calculator</title>
</head>
<body>
<form action="/" method="post">
<h1>Calculator</h1>
<input type="text" name="num1" placeholder="Number 1">
<input type="text" name="num2" placeholder="Number 2">
<button action="/" type="button" name="button">Submit</button>
</form>
</body>
</html>
Node Js code:
//jshint esversion:6
const express=require("express");
const app=express();
app.get("/", function(req,res){
res.sendFile( __dirname+"/index.html");
});
app.post("/", function(req,res){
res.send("Thanks for post");
});
app.listen(3000, function(){
console.log("Server Started On Port 3000");
});
Your button type should be Submit
<button type="submit" value="Submit">Calculator</button>

How to redirect to a different Window in ElectronJS without a new Window

I have a question on how to redirect to a different page with ElectronJs.
The documentation only covered how to open a new window. But in my case, I do not wish to open a new window. This is what I've been trying so far but it's not responding:
login.js
const {BrowserWindow} = require('electron')
const loginBtn = document.getElementById('loginBtn')
loginBtn.addEventListener('click', () => {
let win = BrowserWindow
win.on('close', () => { win = null })
win.loadURL('file:///Users/cadellteng/Desktop/Timetrack/main_page.html')
win.show()
})
The above codes are modified from existing open a new page in a new browser window codes. I tried the following without much success too
loginBtn.addEventListener('click', () => {
window.location.href = 'main_page.html'
})
Hoping for someone to assist. I wasn't able to find helpful assistance on StackOverflow so I'm opening this thread, but if someone did indeed has asked this before, I'll be happy to delete this thread too. Just let me know. Thanks.
If you need to see my HTML, here it is:
login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Timetrack</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto">
<link rel="stylesheet" href="assets/fonts/fontawesome-all.min.css">
<link rel="stylesheet" href="assets/fonts/ionicons.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<link rel="stylesheet" href="assets/css/Login-Form-Clean.css">
<link rel="stylesheet" href="assets/css/styles.css">
</head>
<body style="background-color: rgb(241,247,252);">
<nav class="navbar navbar-light navbar-expand-md" style="background-color: black;">
<div class="container-fluid"><a class="navbar-brand app-name" id="app-name" href="#" style="font-family: Roboto, sans-serif;width: 165px;color: white;"><b>Timetrack <sub>by Pyxel Inc</sub></b></a></div>
</nav>
<div class="flex-fill login-clean" style="background-size: auto;">
<form method="post">
<h2 class="sr-only">Login Form</h2>
<div class="illustration"><i class="icon ion-ios-clock"></i></div>
<div class="form-group"><input class="form-control" type="email" name="email" placeholder="Email"></div>
<div class="form-group"><input class="form-control" type="password" name="password" placeholder="Password"></div>
<div id="loginBtn" class="form-group"><button class="btn btn-primary btn-block" type="submit">Log In</button></div><a class="forgot" href="#">Forgot your email or password?</a></form>
</div>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="login.js"></script>
</body>
</html>
You can use an electron.js file to setup the electron window and import in this file an app.js server with express. In this way you can use express for redirect to other page as a web application.
This is the electron.js file
const server = require('./app');
var path= require('path')
const { app, BrowserWindow } = require('electron')
var mainWindow
function createWindow() {
mainWindow = new BrowserWindow({
width: 1280,
height: 720,
icon: path.join(__dirname, 'public/img/icona-app.png'),
autoHideMenuBar: true,
useContentSize: true,
resizable: true,
webPreferences: {
devTools: false
}
});
mainWindow.loadURL('http://localhost:8080/');
}
app.on('ready', createWindow)
And this is the app.js file
var express = require('express')
var app = express()
app.listen(8080, function () {
console.log('Your application is listening on port 8080!')
})
app.get('/', function(req, res){
res.sendFile(__dirname + "/public/login.html");
})
module.exports=app
And then you must edit your package.json file
You must edit this two attributes:
"main": "electron.js",
"scripts": {
"start": "npm install && electron electron.js --no-sandbox"
},
To start the application write npm start

Connection-route of node.js taking wrong parameters informations

I've a problem with my node.js application.
I'm using the packages connection, connection-route, socket.io and ejs.
My application provides informations to the html page (connected via socket.io), these informations are managed by an ejs template.
When I reach a destination with a parameter, like http://localhost:5001/machine/:id2, something strange happens.
The connection route code is the following:
router.get('/machine/:mac_id', function (req, res, next) {
var mac_index = req.params.mac_id.slice(1,req.params.mac_id.length);
console.log(mac_index);
res.writeHead(200, { 'Content-Type': 'text/html' });
var str = mod_fs.readFileSync(mac_route + '/index.html', 'utf8') ;
var ret = mod_ejs.render(str, {
filename: mac_route,
title: "Machine Overview",
/* other informations */
});
res.end(ret);
}
The variable mac_route contains the path to the file index.html, which is loaded correctly.
The problem lies in the mac_index variable. On the console are printed 3 rows:
id2
unctions.js
query-1.9.1.js
The first row is obviously correct, the last 2 rows are obviously not correct, infact these are two javascript files (my file functions.js and the file for jquery jquery-1.9.1.js).
These files are included in the header of the index.html file.
HTML STRUCTURE:
header.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> <%= title %> </title>
<link rel='stylesheet' href='/style.css' type="text/css"/>
<script src="http://localhost:5001/socket.io/socket.io.js"></script>
<script language="javascript" type="text/javascript" src="functions.js"></script>
<script language="javascript" type="text/javascript" src="jquery-1.9.1.js"></script>
</head>
<body>
<div id="header">
...
</div>
<div id="page">
index.html
<% include /header.html %>
<div id="commands">
...
</div>
<div id="main">
... code of the page, manage informations received ...
</div>
<% include /footer.html %>
footer.html
<div id="footer">
...
</div>
</div> <!-- Close the "page" div opened in the header //-->
</body>
</html>
I can't find where's the mistake.
Why the file's names are taken as parameter of the req object?
The normalized URL for those files is:
http://localhost:5001/machine/functions.js
http://localhost:5001/machine/jquery-1.9.1.js
Those match your route (/machine/:mac_id), so they will be handled by it.
Try including the connect.static middleware before your routes:
app.use(connect.static(__dirname));
(this assumes your Connect app is stored in the app variable and the JS files are in the same directory as your Node script; if not, change __dirname to point to the directory where the JS files are located).

Referencing external files with a node.js server?

I have an Ubuntu 10.04 hosting server which allows me to run node.js off of it. I'm making an test homepage and I have a few files as follows:
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>iSuperMario</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script src="/nowjs/now.js"></script>
<script src="js/chat.js"></script>
</head>
<body>
<div id="wrapper">
<div id="header">
<img src="images/green_pipe_960.png">
<img src="images/orange_pipe_960.png">
</div>
<div id="chat">
<input type="text" id="text-input">
<input type="button" value="Send" id="send-button">
</div>
<div id="content">
</div>
<div id="rooms">
</div>
</div>
</body>
</html>
reset.css and style.css (which both just contain styling for the index.html page
chat.js (which contains some scripting to implement the barebones chat function for the index.html page)
server.js which is a node.js server utilizing nowjs to serve the index.html page on port 8080 of the Ubuntu server and to implement the chat function:
var fs = require('fs');
var server = require('http').createServer(function(req, response){
fs.readFile(__dirname+'/index.html', function(err, data){
response.writeHead(200, {'Content-Type':'text/html'});
response.write(data);
response.end();
});
});
server.listen(8080);
var everyone = require("now").initialize(server);
everyone.connected(function(){
console.log("Someone has joined!");
});
everyone.disconnected(function(){
console.log("Someone has left...");
});
everyone.now.distributeMessage = function(message){everyone.now.receiveMessage(message);};
So, when I view the page from the server in a browser, none of the external resources (reset.css, style.css, chat.js, green_pipe_960.png and orange_pipe_960.png) are connected properly.
How should I enable these? I mean, if I had to, and it simplified the process a great deal, I could always include the external styles and scripts in index.html. But, the images could never be embedded (at least I think xD).
Thanks!
You need to set your file structure as follows
= main
= index.html
= css
= reset.css
= style.css
= js
= chat.js
= images
= green_pipe..
= orange_pipe..
Alternatively you can change your urls to match your real file structure.
I would like to recommend you use express or something else if you want to server something beyond a very basic prototype.
This webpage might help. Serving Static Files from Node.js.

Resources