Serving static frontend JS file with Express JS - javascript

Hi I am having trouble Loading the frontend JS file in Express server. My file structure is like this
My Server Code -
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "views"));
app.use('/static', express.static(path.join(__dirname, 'public')))
app.get("/", (req, res) => {
// check if user is logged in, by checking cookie
let username = req.cookies.username;
if(username){
return res.sendFile(path.join(__dirname, "public/index.html"))
}else{
res.redirect("/login");
}
});
I can successfully Load the html file
But the script file index.js is not loading and i am not able to function
<script src="index.js"></script>
Can you tell me what is it i am doing wrong

The "public" folder on the back end usually refers to a folder on the server mapped to the root path of the URL. Hence try replacing the /static path with just / in express routing, and put checks for logged in status (and any other HTTP GET request processing for server root paths that does not involve serving static files) before setting up the static server itself:
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "views"));
app.use('/static', express.static(path.join(__dirname, 'public')))
app.get("/", (req, res) => {
// check if user is logged in, by checking cookie
let username = req.cookies.username;
if(username){
return res.sendFile(path.join(__dirname, "public/index.html"))
}else{
res.redirect("/login");
}
// set up static server on root path:
app.use('/', express.static(path.join(__dirname, 'public')))
});

Related

Express static files not working properly

I'm doing a simple node project to practice but i can't manage to serve html file with its css styles.
I believe that it worked fine for me before with the same code but now I don't understand why it doesn't run.
I searched about it and copied some code replacing the directory's name but it doesn't change anything.
Here is my code.
I also tried with path module to join the file name and the directory name.
app.use(express.static('public'));
app.get('/', (req, res)=>{
res.send("Welcome to our website");
});
app.get("/signup", (req, res)=>{
res.sendFile(__dirname + "/index.html");
});
//My directory:
testapp1
--node_modules
--public
--styles.css
--index.html
--app.js
--package.json
--package-lock.json
In the network tab of the developer console, it says that:
status: canceled
type: stylesheet
initiator: index.html
Size: 0B
time: 29ms
waterfall: "nothing"
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function (req, res, next) {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
Try that instead.

Route an entire folder and its content

I want to protect a folder and its content by redirecting the user back to index.
I've tried this, but it only works partially.
var express = require('express');
var path = require('path');
var http = require('http');
var app = express();
app.set('port', 8080);
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'views')));
app.get('/', function(req, res) {
res.render('index.ejs');
});
app.get('/protected/*', function(req, res, next) {
res.redirect('/');
next();
});
//activating server
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
This routes, for example, "localhost:8080/protected" and "localhost:8080/protected/asdf", but not "localhost:8080/protected/otherPage.html".
In this case asdf is not an actual file, but otherPage.html is. So if the file is there it doesn't redirect, but if it is not then it redirects. Why is this?
Your line dealing with static files app.use(express.static(path.join(__dirname, 'views'))); appears before app.get('/protected') so its being matched first.
If you moved the static handler to later in the code this would work as you require.
However, I would recommend splitting the static items into a separate folder to guard against accidentally revealing any server-side code you might be including in ejs files in the views folder.

How to structure my project folder when building a secured NodeJs REST API

I am building a REST API using NodeJS and Express, powered by a MongoDB database.
I've been struggling for days now trying to get the right folder structure nailed down. So far, I can connect to my database and add new users without an API, but by simply doing GET, POST, etc. requests. I've seen several tutorials online on how to build API using node, but none of them have a more standardized way for setting their folder structure. And that is the reason why I am having such a hard time making it work given my current folder structure.
Here is my Folder Structure
app
---models
------user.js
---api.js
---routes.js
config
---auth.js
---database.js
---passport.js
public
views
package.json
server.js
Server.js
// server.js
// set up ======================================================================
// get all the tools we need
var express = require('express');
var app = express();
var port = process.env.PORT || 2016;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var configDB = require('./config/database.js');
// configuration ===============================================================
mongoose.connect(configDB.url); // connect to our database
require('./config/passport')(passport); // pass passport for configuration
app.configure(function() {
// set up our express application
app.use(express.logger('dev')); // log every request to the console
app.use(express.cookieParser()); // read cookies (needed for auth)
app.use(express.bodyParser.json()); // get information from html forms
app.use(bodyParser.urlencoded({ extended: true }));
app.set('views', path.join(__dirname + '/views'));
app.set('view engine', 'ejs'); // set up ejs for templating
// set the static files location /public/img will be /img for users
app.use(express.static(__dirname + '/public'));
// required for passport
app.use(express.session({ secret: 'xxxxxxxxx' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
});
// routes ======================================================================
// require('./app/routes')(app, passport); // load our routes and pass in our app and fully configured passport
// require('./app/api')(api, passport);
app.use('/', require('./app/routes')(app, passport));
app.use('/api', require('./app/api')(api, passport));
// error handlers
// Catch unauthorised errors
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
res.status(401);
res.json({"message" : err.name + ": " + err.message});
}
next();
});
// launch ======================================================================
app.listen(port);
console.log('Live on port ' + port);
api.js
var User = require('./models/user');
var express = require('express');
var apiRoutes = express.Router();
app.use('/api', apiRoutes);
module.exports = function(apiRoutes, passport){
apiRoutes.get('/testapi', function (req,res) {
res.json({SecretData: 'abc123'});
});
}
Every time I hit the endpoint /testapi I get the error "Cannot GET /testapi"
I think my main issue is how to organize my files and folder properly and import/require them the right way. Can anyone help me figure this out?
Server.js
on this line app.use('/api', require('./app/api')(api, passport));
Here you are telling Express to use ./app/api as an middleware by passing "api" and "passport" as arguments.
where you have defined api variable ?
Lets assume its a typo.. in that case from "app/api.js" you are exporting a function and you trying to execute it in server.js app.use('/api', require('./app/api')(api, passport)); which returns undefined.
Express will be expecting a function as middleware not a return value from function.
app/api.js
on line 4 you have app.use('/api', apiRoutes); which doesn't make any sense, because api.js has no idea about "app".
Cleanup your server.js and api.js and try again
This tutorial might help Node with Express

Node express does not render the right view

Here is my project structure
public/
css/
images/
js/
routes/
index.js
users.js
views/
AdminView/
layouts/
layout.hbs
index.hbs
I am currently having a problem where I cannot load the right view on my Node Express app. Here is some of my code
users.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond');
});
router.get('/admin', function(req, res, next) {
res.render(__dirname + 'AdminView/pages/tables/job-posts', {title: 'Admin Page'});
});
module.exports = router;
app.js *a portion of it
// view engine setup
app.engine('hbs', hbs({extname: 'hbs', defaultLayout: 'layout' , layoutsDir: __dirname + '/views/layouts'}));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
// Render the main view static files
app.use(express.static(path.join(__dirname, 'public'))); // Render for /
app.use("/career", express.static(__dirname + '/public')); // Render for /carrer/
app.use("/career/form", express.static(__dirname + '/public')); // Render for /carrer/form
app.use("/users", express.static(__dirname + "/views/AdminView")); // Render for /users
// Problematic code below
app.use("/users/admin", express.static(__dirname + "/views/AdminView")); // Render for /users/admin
app.use('/', routes);
app.use('/users', users);
Here is the problem. When I am trying to access /users/admin, I do not know why it renders the index page on the AdminView folder full with the css, js and images, while it should be rendering the one I specified on the routing (AdminView/pages/tables/job-posts).
Though, if I comment the line that is problematic above, it loads the html file which i specified on the routing file, but does not render the static files.
Side note:
I have 2 website, one is the main website, the other one is the admin page. All of the admin resources are on the views/AdminView folder
Full app.js http://pastebin.com/YFAbcKRz
Full users.js http://pastebin.com/TZrdFYA2
The file what I trying to load is on the picture below

Express failing to look up view

I am trying to create a SPA app, but when i start my application it does an infinte loop leading to a crash. I am using ExpressJS 4.3.0
App architecture:
public
--partials
----index.jade
server.js
My express code:
var app = express();
var port = process.env.PORT || 8080;
app.set('views', __dirname + '/public');
app.set('view engine', 'jade');
app.use(express.static(__dirname + '/public'));
app.get('*', function (req, res) {
res.render('partials/index');
});
app.get('/', function (req, res) {
res.render('partials/index');
});
app.get('/partials/:name', function (req, res) {
res.render('/partials/' + req.params.name);
});
app.listen(port);
console.log('Server is running on port: ' + port);
If i use
res.render('/partials/index');
i recieve a message:
Error: Failed to lookup view "/partials/index" in views directory
Its because of view lookup function in express view lookup
if (!utils.isAbsolute(path)) path = join(this.root, path);
which makes it assume '/partial/index' is already an absolute path and didnt prefix with root path.
Also move the
app.get('*', function (req, res) {
res.render('partials/index');
});
to end else it will always serve the index view.
It looks like you shouldn't have a preceding / in your view path in render(). Just use 'partials/' + req.params.name.
On a related note, are you sure you want your actual view files to be public? Usually they are stored outside of the public static directory (e.g. ./public contains static assets and ./partials contains views). Also that way you don't have to keep prefixing view paths with partials/.

Categories