How to fetch images from node.js server's folder in URL? - javascript

Does anybody know how to fetch images from node.js server's folder in URL?
In my folder structure I have folder data and inside there is subfolder img with image. I want to access this image with URL, like this:
http://localhost:3000/data/img/default.jpg
but when I enter it into browser I always get this error:
Page Not Found /data/img/default.jpg is not a valid path.
server.js:
'use strict';
/**
* Module dependencies.
*/
var init = require('./config/init')(),
config = require('./config/config'),
mongoose = require('mongoose');
var express = require('express');
/**
* Main application entry file.
* Please note that the order of loading is important.
*/
// Bootstrap db connection
var db = mongoose.connect(config.db, function(err) {
if (err) {
console.error('\x1b[31m', 'Could not connect to MongoDB!');
console.log(err);
}
});
// Init the express application
var app = require('./config/express')(db);
// Bootstrap passport config
require('./config/passport')();
app.use(express.static('data/img'));
// Start the app by listening on <port>
app.listen(config.port);
// Expose app
exports = module.exports = app;
// Logging initialization
console.log('MEAN.JS application started on port ' + config.port);
express.js:
'use strict';
/**
* Module dependencies.
*/
var express = require('express'),
morgan = require('morgan'),
bodyParser = require('body-parser'),
session = require('express-session'),
compress = require('compression'),
methodOverride = require('method-override'),
cookieParser = require('cookie-parser'),
helmet = require('helmet'),
passport = require('passport'),
mongoStore = require('connect-mongo')({
session: session
}),
flash = require('connect-flash'),
config = require('./config'),
consolidate = require('consolidate'),
path = require('path');
module.exports = function(db) {
// Initialize express app
var app = express();
// Globbing model files
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
require(path.resolve(modelPath));
});
// Setting application local variables
app.locals.title = config.app.title;
app.locals.description = config.app.description;
app.locals.keywords = config.app.keywords;
app.locals.facebookAppId = config.facebook.clientID;
app.locals.jsFiles = config.getJavaScriptAssets();
app.locals.cssFiles = config.getCSSAssets();
// Passing the request url to environment locals
app.use(function(req, res, next) {
res.locals.url = req.protocol + '://' + req.headers.host + req.url;
next();
});
// Should be placed before express.static
app.use(compress({
filter: function(req, res) {
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
},
level: 9
}));
// Showing stack errors
app.set('showStackError', true);
// Set swig as the template engine
app.engine('server.view.html', consolidate[config.templateEngine]);
// Set views path and view engine
app.set('view engine', 'server.view.html');
app.set('views', './app/views');
// Environment dependent middleware
if (process.env.NODE_ENV === 'development') {
// Enable logger (morgan)
app.use(morgan('dev'));
// Disable views cache
app.set('view cache', false);
} else if (process.env.NODE_ENV === 'production') {
app.locals.cache = 'memory';
}
// Request body parsing middleware should be above methodOverride
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(methodOverride());
// Enable jsonp
app.enable('jsonp callback');
// CookieParser should be above session
app.use(cookieParser());
// Express MongoDB session storage
app.use(session({
saveUninitialized: true,
resave: true,
secret: config.sessionSecret,
store: new mongoStore({
db: db.connection.db,
collection: config.sessionCollection
})
}));
// use passport session
app.use(passport.initialize());
app.use(passport.session());
// connect flash for flash messages
app.use(flash());
// Use helmet to secure Express headers
app.use(helmet.xframe());
app.use(helmet.xssFilter());
app.use(helmet.nosniff());
app.use(helmet.ienoopen());
app.disable('x-powered-by');
// Setting the app router and static folder
app.use(express.static(path.resolve('./public')));
// Globbing routing files
config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
require(path.resolve(routePath))(app);
});
// Assume 'not found' in the error msgs is a 404. this is somewhat silly, but valid, you can do whatever you like, set properties, use instanceof etc.
app.use(function(err, req, res, next) {
// If the error object doesn't exists
if (!err) return next();
// Log it
console.error(err.stack);
// Error page
res.status(500).render('500', {
error: err.stack
});
});
// Assume 404 since no middleware responded
app.use(function(req, res) {
res.status(404).render('404', {
url: req.originalUrl,
error: 'Not Found'
});
});
return app;
};

It's like you have already set your data/img folder as a static folder in the line below:
app.use(express.static('data/img'));
In that case, you should be accessing images placed in the static folder above using below url:
http://localhost:3000/default.jpg
I will however advice you use Node's global variable __dirname to indicate the root of the static folder but this depends on where your server.js is located within your file structure.
The js file containing the snippets below is located in the root and I have /data/img folder from the root as well and I am able to retrieve the image using /image name.
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/data/img'));
app.listen(3500, function () {
console.log('Express server is listening, use this url - localhost:3500/default.png');
});
See if this helps you. If it does, make sure you know the reason for using the __dirname global variable name.
SO1

Related

Nodejs and mongodb connection error after upgrading Mongo

Am trying to build some Todo app using Express and mongodb but i have some problems with nodejs and mongo connection and i searched about it on internet but didn't get any solution for my problem.
When trying to connect to mongodb from node js as in this code:
// This to require Express framework to use it
const express = require('express');
const csrf = require('csurf');
const errorhandler = require('errorhandler')
// Loads the piece of middleware for sessions
const logger = require('morgan');
const favicon = require('serve-favicon');
const methodOverride = require('method-override');
// This is a middleware to handle requests and parse the forms
const bodyParser = require('body-parser');
const routes = require('./routes');
const tasks = require('./routes/tasks');
const http = require('http');
const path = require('path');
const mongoskin = require('mongoskin');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const db = mongoskin.db("mongodb://localhost:27017/todo");
// Define object of express
const app = express();
app.use((req, res, next) => {
req.db = {};
req.db.tasks = db.collection('tasks');
next();
});
// This makes us can access app name from any JADe template
app.locals.appname = "Todo App Express.js";
app.locals.moment = require('moment');
// set app port to 8081 port
app.set('port', 8081);
// these tells express where's project safe templates in, and tell what's
// their extension will be.
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
// show express favicon in browser
app.use(favicon(path.join('public', 'favicon.ico')));
// this will print requests in terminal
app.use(logger('dev'));
// using body parser to can parse requests
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(methodOverride());
// to use CSRF we need cookie parser
app.use(cookieParser('CEAF3FA4-F385-49AA-8FE4-54766A9874F1'));
app.use(session({
secret: '59B93087-78BC-4EB9-993A-A61FC844F6C9',
resave: true,
saveUninitialized: true
}));
app.use( csrf() );
// to process LESS stylesheets into CSS ones
app.use(require('less-middleware')(path.join(__dirname, 'public')));
// to use other static files which inside public
app.use(express.static(path.join(__dirname, '/public')));
// to make csrf used in templates
app.use( (req, res, next) => {
res.locals._csrf = req.csrfToken();
return next();
});
app.param('task_id', (req, res, next, taskId) => {
req.db.tasks.findById(taskId, (error, task) => {
if (error) return next(error);
if (!task) return next(new Error('Task is not found.'));
req.task = task;
return next();
});
});
// homepage to show our todo homepage
app.get('/', routes.index);
// list all created tasks [in-progress ones]
app.get('/tasks', tasks.list);
// this to mark all task as completed in one step
app.post('/tasks', tasks.markAllcompleted);
// this to add new task
app.post('/tasks', tasks.add);
// this to mark specfic task as completed
app.post('/tasks/:task_id', tasks.markcompleted);
// this to delete specfic task by :task_id
app.delete('/tasks/:task_id', tasks.del);
// this to list all completed tasks
app.get('/tasks/completed', tasks.completed);
// this 404 error page to show it if user requested any route doesn't exist in our routes
app.all('*', (req, res) => {
res.status(404).send();
});
if ('development' == app.get('env')) {
app.use(errorhandler());
}
// create our server
http.createServer(app).listen(app.get('port'),
() => {
console.log('Express server listening on port ' + app.get('port'));
});
I go this error in terminal:
/home/luffy/nodejs-train/todo-express-mongodb/node_modules/mongodb/lib/mongo_client.js:804
throw err;
^
TypeError: Cannot read property 'apply' of undefined
at EventEmitter.<anonymous> (/home/luffy/nodejs-train/todo-express-mongodb/node_modules/mongoskin/lib/collection.js:51:21)
at Object.onceWrapper (events.js:272:13)
at EventEmitter.emit (events.js:180:13)
at /home/luffy/nodejs-train/todo-express-mongodb/node_modules/mongoskin/lib/utils.js:134:27
at result (/home/luffy/nodejs-train/todo-express-mongodb/node_modules/mongodb/lib/utils.js:414:17)
at executeCallback (/home/luffy/nodejs-train/todo-express-mongodb/node_modules/mongodb/lib/utils.js:406:9)
at /home/luffy/nodejs-train/todo-express-mongodb/node_modules/mongodb/lib/mongo_client.js:271:5
at connectCallback (/home/luffy/nodejs-train/todo-express-mongodb/node_modules/mongodb/lib/mongo_client.js:940:5)
at /home/luffy/nodejs-train/todo-express-mongodb/node_modules/mongodb/lib/mongo_client.js:801:11
at process._tickCallback (internal/process/next_tick.js:112:11)
[nodemon] app crashed - waiting for file changes before starting...
And in my Firefox got :
Unable to connect
Firefox can’t establish a connection to the server at localhost:8081.
Using NodeJS V9.8.0 and mongodb v3.4.14
This was a problem even we faced and it seems it just has to do with the consequent versions of 'mongoskin'. Why don't you try and use mongodb ?
Saves time and a much better option!

Node, module usage structure

I've been trying to understand how to set up Stripe for my app but am having problems with the implementation of the module. Normally when using a module i would require it in the top of the file to be able to use it but I'm not sure how to do this here in the paymentController file or if i even need to. I imported the Stripe npm, so does that i mean that i can access it globally? Well as you see i'm quite new to this and would like to understand how to structure this so that the payments work.
app.js file:
angular.module('userApp', ['appRoutes', 'userControllers', 'userServices', 'ngAnimate', 'mainController', 'authServices', 'managementController', 'paymentController'])
.config(function($httpProvider) {
$httpProvider.interceptors.push('AuthInterceptors');
});
paymentController file:
angular.module('paymentController', [])
.controller('paymentCtrl', function($scope) {
var app = this;
});
Server.js file:
var express = require('express'); // ExperssJS Framework
var app = express(); // Invoke express to variable for use in application
var port = process.env.PORT || 8080; // Set default port or assign a port in enviornment
var morgan = require('morgan'); // Import Morgan Package
var mongoose = require('mongoose'); // HTTP request logger middleware for Node.js
var bodyParser = require('body-parser'); // Node.js body parsing middleware. Parses incoming request bodies in a middleware before your handlers, available under req.body.
var router = express.Router(); // Invoke the Express Router
var appRoutes = require('./app/routes/api')(router); // Import the application end points/API
var path = require('path'); // Import path module
var passport = require('passport'); // Express-compatible authentication middleware for Node.js.
var social = require('./app/passport/passport')(app, passport); // Import passport.js End Points/API
app.use(morgan('dev')); // Morgan Middleware
app.use(bodyParser.json()); // Body-parser middleware
app.use(bodyParser.urlencoded({ extended: true })); // For parsing application/x-www-form-urlencoded
app.use(express.static(__dirname + '/public')); // Allow front end to access public folder
app.use('/api', appRoutes); // Assign name to end points (e.g., '/api/management/', '/api/users' ,etc. )
mongoose.connect('mongodb://localhost:27017/tutorial', function(err) {
if (err) {
console.log('Not connected to the database: ' + err);
} else {
console.log('Successfully connected to MongoDB');
}
});
// Set Application Static Layout
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/app/views/index.html')); // Set index.html as layout
});
// Start Server
app.listen(port, function() {
console.log('Running the server on port ' + port); // Listen on configured port
});
I'd recommend following what's shown for Node in this Stripe tutorial:
https://stripe.com/docs/charges
Just like your other includes, you want something like this at the top of any JS file that will use the Stripe library:
var stripe = require('stripe')('sk_my_secret_key')
Then, elsewhere in the same file, you can call any Stripe library methods you need:
stripe.charges.create(…)
Of course, in production you'll want to build a proper 12 Factor app[1] and put your secrets in environment variables or configuration files.
[1] https://12factor.net/config

How can I make session variables accessible to sub application

I am building an api that will interface with the MongoDB database and have mounted it as a subapplication. I have defined a session variable in my server controller.
However, any time that the server files need to talk to the api files the session variables are never passed off.
Heres the app.js file
//app.js file
'use strict';
process.env.NODE_ENV = 'development';
var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var flash = require('connect-flash');
var helmet = require('helmet');
var app = express();
app.use(helmet());
var port = process.env.PORT || 3000;
mongoose.connect("mongodb://localhost:27017/striv4");
var db = mongoose.connection;
// mongo error
db.on('error', console.error.bind(console, 'connection error:'));
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: false,
store: new MongoStore({
mongooseConnection: db
})
}));
app.use(flash());
// make user ID available in templates
app.use(function (req, res, next) {
res.locals.currentUser = {
username:req.session.username,
id: req.session.userId
};
next();
});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser('secreter'));
app.use(logger('dev'));
var api = require('./app_api/routes/index');
var serverRoutes = require('./server/routes/index');
//static file middleware
app.use(express.static(__dirname + '/public'));
app.set('views',__dirname +'/server/views');
app.set('view engine','pug');
app.use('/',serverRoutes);
app.use('/api',api);
//custom error handler
app.use(function(error, req, res, next) {
res.status(error.status || 500);
res.send('Error: '+error.message);
});
app.listen(port);
console.log('Listening on port: '+port);
You've got the whole program listed so there is more than one way for this to have gone wrong. Here are my suggestions to fix this:
Check the version of express-session you've installed. (Just run npm ls in the terminal and in your root Node app folder where you're package.json file is). If it's equal to or greater than v1.5.0, you don't need the cookie-parser for sessions anymore. Comment out the app.use line for the cookie parser and see if this works.
If you still need cookie parser for some other reason, you should use the same secret for sessions and the cookie parser. In your code, you've set two different values for secret.
I've seen that the other big failure for sessions occurs if the session store is not correctly connected to your Node app. Cross-check that the database is available and working. In my experience, Express sessions will fail silently if it can't get to the DB.
Hope this helps.

Blocking static file access in expressJS

I'm trying to block certain files in my site from being publicly accessible. For example, if you go to mysite.com/package.json instead of displaying it in the browser i just want to send and error or redirect back to my homepage or something. I feel like this should be easy... but i haven't been able to get anything to work. there isn't anything complicated about the site, and it's running of a fairly simple server.js
var appRoot = __dirname,
express = require('express'),
chalk = require('chalk'),
mongoose = require('mongoose'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
path = require('path'),
errorhandler = require('errorhandler'),
os = require('os'),
http = require('http'),
Routes;
// -----------------------------
// Configuration
// -----------------------------
var port, env, logs;
// Switch some vars based on the ENV
if(process.env.NODE_ENV === 'production'){
port = 3000;
env = 'production';
} else {
port = 8080;
env = 'development';
}
// Express Variables
var app = express();
var router = express.Router();
// Use static files in root
app.use(express.static(__dirname));
// API config
app.use(bodyParser.json());
app.use(methodOverride());
app.use(errorhandler({ dumpExceptions: true, showStack: true }));
// Database
mongoose.connect(mydb);
// Routes / API Config
Routes = require(appRoot + '/routes')(app, router, mongoose);
// After all routes don't match ie. refreshing a page, send index.html
app.get('/*', function(req, res) {
res.sendFile(__dirname + '/index-' + env + '.html');
});
app.listen(port);
I was hoping to do something like:
app.get('/package.json', function(){
res.end('Not allowed');
});
or even before i send it the static html index check if they are trying to access a restricted file. Any suggestions, resources etc are welcomed. If you need any more info just ask.
Based on your comment
You should replace this line:
app.use(express.static(__dirname ));
with this:
app.use('/assets', express.static(__dirname + '/assets'));
app.use('/views', express.static(__dirname + '/views'));

When I navigate to a route directly i get server output, but when I use a link i get the view rendered correctly

I'm a noob and working on mean.js boilerplate.
I've created some routes, but I'm having an issue, where, when I navigate to a certain route ('/articles') i get server output like this:
[{"_id":"5553aa4116a2fddc830b0f66","user":{"_id":"5552398fcf7ada7563db68b7","displayName":"Mo
Bazazi"},"__v":0,"content":"WAHATTATA","title":"Fifth
Examples","created":"2015-05-13T19:47:13.905Z"}]
but i want to ge the rendered view, even when I manually type in the route - does anyone have any suggestions?
here part of my express config
use strict';
/**
* Module dependencies.
*/
var fs = require('fs'),
http = require('http'),
https = require('https'),
express = require('express'),
morgan = require('morgan'),
bodyParser = require('body-parser'),
session = require('express-session'),
compress = require('compression'),
methodOverride = require('method-override'),
cookieParser = require('cookie-parser'),
helmet = require('helmet'),
passport = require('passport'),
mongoStore = require('connect-mongo')({
session: session
}),
flash = require('connect-flash'),
config = require('./config'),
consolidate = require('consolidate'),
path = require('path');
module.exports = function(db) {
// Initialize express app
var app = express();
// Globbing model files
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
require(path.resolve(modelPath));
});
// Setting application local variables
app.locals.title = config.app.title;
app.locals.description = config.app.description;
app.locals.keywords = config.app.keywords;
app.locals.facebookAppId = config.facebook.clientID;
app.locals.jsFiles = config.getJavaScriptAssets();
app.locals.cssFiles = config.getCSSAssets();
// Passing the request url to environment locals
app.use(function(req, res, next) {
res.locals.url = req.protocol + '://' + req.headers.host + req.url;
next();
});
// Should be placed before express.static
app.use(compress({
filter: function(req, res) {
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
},
level: 9
}));
// Showing stack errors
app.set('showStackError', true);
// Set swig as the template engine
app.engine('server.view.html', consolidate[config.templateEngine]);
// Set views path and view engine
app.set('view engine', 'server.view.html');
app.set('views', './app/views');
So Claies was right - this is an HTML5 issue - I've been working on this a little and trying to set up a catch all for express config - I've added this section below:
// Setting the app router and static folder
app.use(express.static(path.resolve('./public')));
app.get('/', function(req, res) {
res.render('index');
});
// Globbing routing files
config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
require(path.resolve(routePath))(app);
});
app.get('*', function(req, res) {
res.redirect('/');
});
The problem is that I'm using mean.js boilerplate, and they have custom glob based routing, which doesn't play well with my catchall i.e. my resources wont work properly with the catchall as they are, although they are rerouting to the correct templates - any thoughts?

Categories