I am sending a simple get request (without any params) through chrome/postman When and after 2 minutes I got an error messsage.
I expected to get an answer "cannot get" on sending get request to localhost:3030
I expect to get the JSON file on my db when I send a get request to localhost:3030/api/task
In both cases I get the "loading /thinking" circle and nothing happens.
Error messsages (after 2 minutes of "loading"):
On chrome - After 2 minutes - I got " This site can't be reached" And On Postman "Could not get response
I wrote a console.log on the task controller file and it's even not reaching there.
I am attaching the server.js file. I suspect something is wrong there. I don't want to overload this question.
const cors = require('cors')
const path = require('path')
// const expressSession = require('express-session')
const app = express()
const http = require('http').createServer(app)
// const session = expressSession({
// secret: 'coding is amazing',
// resave: false,
// saveUninitialized: true,
// cookie: { secure: false }
// })
//Express App Config
app.use(express.json())
//app.use(session)
if (process.env.NODE_ENV === 'production') {
app.use(express.static(path.resolve(__dirname, 'public')))
} else {
const corsOptions = {
origin: ['http://127.0.0.1:8080', 'http://localhost:8080', 'http://127.0.0.1:3000', 'http://localhost:3000'],
credentials: true
}
app.use(cors(corsOptions))
}
const taskRoutes = require('./api/task/task.routes')
//const { connectSockets } = require('./services/socket.service')
// routes
const setupAsyncLocalStorage = require('./middlewares/setupAls.middleware')
app.all('*', setupAsyncLocalStorage)
// app.get('/api/setup-session', (req, res) => {
// req.session.connectedAt = Date.now()
// console.log('setup-session:', req.sessionID);
// res.end()
// })
app.use('/api/task', taskRoutes)
//connectSockets(http, session)
//connectSockets(http);
// Make every server-side-route to match the index.html
// so when requesting http://localhost:3030/index.html/car/123 it will still respond with
// // our SPA (single page app) (the index.html file) and allow vue/react-router to take it from there
// app.get('/**', (req, res) => {
// res.sendFile(path.join(__dirname, 'public', 'index.html'))
// })
const logger = require('./services/logger.service')
const port = process.env.PORT || 3030
http.listen(port, () => {
logger.info('Server is running on port: ' + port)
})
There are 2 possible reasons:
You aren't going to localhost:3030.
process.env.PORT is being set to something other than 3030.
Once you check these, it should go away.
Related
I am trying to make Postman work with React JS using express. I am following a Mern Stack Development tutorial in free code camp. I have Cors extension enabled in my browsers, both in Chrome and in Edge. I keep getting this message in localhost:5000 "Cannot get /" and get this message {"msg":"This is CORS-enabled for an allowed domain."} in localhost:5000/users/add. My code looks something like this:
This is my server.js
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();
const app = express();
const port = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
const uri = process.env.ATLAS_URI;
mongoose.connect(uri,{useNewUrlParser: true, useCreateIndex:true, useUnifiedTopology:true});
const connection= mongoose.connection;
connection.once('open', () =>{
console.log("Mongodb database connection established successfully");
})
const exercisesRouter= require('./routes/exercises');
const usersRouter= require('./routes/users');
var allowlist = ['http://localhost:5000']
var corsOptionsDelegate = function (req, callback) {
var corsOptions;
if (allowlist.indexOf(req.header('Origin')) !== -1) {
corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
} else {
corsOptions = { origin: false } // disable CORS for this request
}
callback(null, corsOptions) // callback expects two parameters: error and options
}
app.use('./exercises',exercisesRouter);
app.use('./users', usersRouter);
app.get('/users/add', cors(corsOptionsDelegate), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for an allowed domain.'})
})
app.listen(port, ()=>{
console.log(`Server is running on port: ${port}`);
});
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
cords don’t have anything to do with this
Can you tell me where is yow route for “/“ something like this
app.get(“/“, (req,res)=>{
…..
});
Yes exactly. You don’t have it. If the route/endPoint is not declared how do use expect them browsers to show you some else
When browssers open yow link at localhost:5000
They make a get request to “/“. So express just tell’em
Can not get “/“
I do not
I'm trying to use S3, specifically multer-s3, for image upload for a traditional web app that currently has multer/file system file upload (GitHub repo with previous code before the failed S3 upload attempt can be found here). The app is deployed to Heroku, which has ephemeral file storage, so the old setup is a no-go.
I tried to use multer-s3 to do it based on this tutorial https://www.youtube.com/watch?v=ASuU4km3VHE&t=1364s, but got up to about 20 mins in, trying to send the POST request to the new image-upload route but am getting a 500 error, whereas in the tutorial an AWS image path is provided in the response.
Here's what I tried so far:
I created a bucket and get my access code and keys. In my S3 bucket settings, under Permissions -> Block public access, I set everything to off. I also added CORS config code as suggested by Heroku here (but I still get a 500 error without it).
In the util folder, I added a file named file-upload.js with this code (I'm using a Nodemon.json file for the config keys):
const aws = require('aws-sdk');
const multer = require('multer');
const multerS3 = require('multer-s3');
const { uuid } = require('uuidv4');
aws.config.update({
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
region: 'us-west-2',
});
const s3 = new aws.S3();
const upload = multer({
storage: multerS3({
s3,
bucket: 'nodejs-shop',
acl: 'public-read',
// Called when saving image to AWS
metadata(req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
// Called before saving image to AWS
key(req, file, cb) {
cb(null, uuid());
},
}),
});
module.exports = upload;
In the routes folder, I added a file named file-upload.js, with this code:
const express = require('express');
const router = express.Router();
const upload = require('../util/file-upload');
// Will send image under this key 'image' in request to server
const singleUpload = upload.single('image');
router.post('/image-upload', (req, res, next) => {
// Callback function called after image is uploaded or will get error from server
singleUpload(req, res, (err) => {
return res.json({ imageUrl: req.file.location });
});
});
module.exports = router;
In app.js, I imported the routes file const fileRoutes = require('./routes/file-upload'); and added the middleware after the authRoutes middleware app.use(fileRoutes);. I also commented out all the previously used multer code in app.js.
Current app.js code:
const path = require('path');
const fs = require('fs');
// const https = require('https');
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);
const csrf = require('csurf');
const flash = require('connect-flash');
// const multer = require('multer');
// const { uuid } = require('uuidv4');
const helmet = require('helmet');
const compression = require('compression');
const morgan = require('morgan');
const errorController = require('./controllers/error');
const User = require('./models/user');
const MONGODB_URI =
// process object is globally available in Node app; part of Node core runtime. The env property contains all environment variables known by process object. Using nodemon.json to store environment variables, but could alternatively use dotenv package for this (see https://www.youtube.com/watch?v=17UVejOw3zA)
`mongodb+srv://${process.env.MONGO_USER}:${process.env.MONGO_PASSWORD}#cluster0-4yuid.mongodb.net/${process.env.MONGO_DEFAULT_DATABASE}`;
const app = express();
const store = new MongoDBStore({
uri: MONGODB_URI,
collection: 'sessions',
});
// Secret used for signing/hashing token is stored in session by default
const csrfProtection = csrf();
// Don't want to start server until file is read in, thus using synchronous version
// const privateKey = fs.readFileSync('server.key');
// const certificate = fs.readFileSync('server.cert');
// Commenting out original file upload method since changed to use AWS S3 for image upload/hosting
// const fileStorage = multer.diskStorage({
// destination: (req, file, cb) => {
// // First arg is for error message to throw to inform multer something is wrong with incoming file and it should not store it; with null, telling multer okay to store it
// cb(null, 'images');
// },
// filename: (req, file, cb) => {
// cb(null, uuid());
// },
// });
// const fileFilter = (req, file, cb) => {
// file.mimetype === 'image/png' ||
// file.mimetype === 'image/jpg' ||
// file.mimetype === 'image/jpeg'
// ? cb(null, true)
// : cb(null, false);
// };
app.set('view engine', 'ejs');
// Setting this explicity even though the views folder in main directory is where the view engine looks for views by default
app.set('views', 'views');
const adminRoutes = require('./routes/admin');
const shopRoutes = require('./routes/shop');
const authRoutes = require('./routes/auth');
const fileRoutes = require('./routes/file-upload');
// Create write stream (for passing to morgan, used to log request data), for logging request data in file instead of console
// flags: 'a': a is for append; new data will be appended to that file (additional log statements are added to end of existing file rather than overwriting it)
const accessLogStream = fs.createWriteStream(
path.join(__dirname, 'access.log'),
{ flags: 'a' }
);
// Set secure response header(s) with Helmet
// In my app, in developer tools (in the network tab) I can see it added one additional response header for localhost, Strict-Transport-Security. This HTTP header tells browsers to stick with HTTPS and never visit the insecure HTTP version. Once a browser sees this header, it will only visit the site over HTTPS for the next 60 days
app.use(helmet());
// Compress assets. Note: Compression is normally done by hosting providers, but deploying to Heroku which does offer it
app.use(compression());
// Log request data using writable file stream created above. Which data is logged and how to format it is passed into funtion
// Also normally handled by hosting providers
// app.use(morgan('combined', { stream: accessLogStream }));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// Commented out since changed to use AWS S3 for image upload/hosting
// app.use(multer({ storage: fileStorage, fileFilter }).single('image'));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/images', express.static(path.join(__dirname, 'images')));
app.use(
session({
secret: 'my secret',
resave: false,
saveUninitialized: false,
store,
})
);
app.use(csrfProtection);
app.use(flash());
app.use((req, res, next) => {
// Locals field: Express feature for setting local variables that are passed into views. For every request that is executed, these fields are set for view that is rendered
res.locals.isAuthenticated = req.session.isLoggedIn;
res.locals.csrfToken = req.csrfToken();
next();
});
app.use((req, res, next) => {
// When you throw an error in synchronous places (outside of callbacks and promises), Express will detect this and execute next error handling middleware. But if error is thrown within async code (in then or catch block), Express error handling middleware won't be executed; app will simply crash; have to use next()
// throw new Error('sync dummy');
if (!req.session.user) {
return next();
}
User.findById(req.session.user._id)
.then((user) => {
if (!user) {
return next();
}
req.user = user;
next();
})
// catch block will be executed in the case of technical issue (e.g., database down, or insufficient permissions to execute findById())
.catch((err) => {
// Within async code snippets, need to use next wrapping error, outside you can throw error
next(new Error(err));
});
});
app.use('/admin', adminRoutes);
app.use(shopRoutes);
app.use(authRoutes);
app.use(fileRoutes);
app.get('/500', errorController.get500);
app.use(errorController.get404);
// Error-handling middleware. Express executes this middleware when you call next() with an error passed to it
app.use((error, req, res, next) => {
// res.status(error.httpStatusCode).render(...);
// res.redirect('/500');
res.status(500).render('500', {
pageTitle: 'Server Error',
path: '/500',
isAuthenticated: req.session.isLoggedIn,
});
});
mongoose
.connect(MONGODB_URI, { useUnifiedTopology: true, useNewUrlParser: true })
.then((result) => {
// First arg for createServer() configures server, second is request handler, in this case, Express application
// Commenting out because just as with request logging and asset compression, it's handled by hosting provider, and browsers don't accept custom/self-signed certificate; will be displayed as insecure with a message that connection is not private
// https
// .createServer({ key: privateKey, cert: certificate }, app)
// .listen(process.env.PORT || 3000);
app.listen(process.env.PORT || 3000);
})
.catch((err) => {
console.log(err);
});
This is my Postman request, similar to the one in the tutorial video, and as you can see I just get a 500 error.
I have this GET request that fetches data from a third party api. I want to check if there is new data every 5-10 minutes or so. Right now i have this setup on my backend.
exports.get_alerts = async (req, res) => {
const alertsUrl = `https://www.g2smart.com/g2smart/api/alert?cpo=${req.params.cpo}&status=Opened&limit=10&page=1`;
const axios = require("axios");
const auth = await refreshToken;
const currTime = moment().subtract(1, "days").format("X");
const newAlertsData = [];
const availableUsers = await axios.get(
"http://localhost:5000/api/schedule/available"
) ....
and on the front end i have this code to send a get request to my alerts api endpoint.
getAlerts = async () => {
axios
.get("/api/alerts/total_fr_hpc")
.then((response) => console.log(response.data))
.catch((err) => console.log(err));
};
timer = (time) => {
const date = new Date(time);
return `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
};
componentDidMount() {
this.alertsInterval = setInterval(this.getAlerts, 900000);
}
componentWillUnmount() {
clearInterval(this.alertsInterval);
My question is can i have all this done on the backend only? I read a bit about websockets but that seems to be only for a continuous 2way connection between the backend and frontend.
I'd like to have something like that towards my third party apis on the node/express server, either fetching data at a set interval or a continuous connection checking for new data without having to make GET requests from my frontend. I want to be able to get new Data and store it into MongoDB even when there is nobody logged in to the client side.
I want that the data the users get is always up to date without having at least one person logged in to trigger the GET requests.
This is how my node/express server is currently setup
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const cors = require("cors");
const path = require("path");
const indexRouter = require("./routes/index");
const apiRouter = require("./routes/api"); //Import routes for "api" area of site
const app = express();
// CORS Middleware
app.use(cors());
app.options("*", cors());
// Bodyparser middleware
app.use(
bodyParser.urlencoded({
extended: false,
})
);
app.use(bodyParser.json());
// DB Config
const db = require("./config/keys").mongoURI;
// Connect to MongoDB
mongoose
.connect(db, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
.then(() => console.log("MongoDB successfully connected"))
.catch((err) => console.log(err));
// Passport middleware
app.use(passport.initialize());
// Passport config
require("./config/passport")(passport);
// Routes
// Add api routes to middleware chain.
app.use("/", indexRouter);
app.use("/api", apiRouter);
// Serve static assets (build folder) if in production
if (process.env.NODE_ENV === "production") {
// Set static folder
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
});
}
const port = process.env.PORT || 5000;
app.listen(port, "0.0.0.0", () =>
console.log(`Server up and running on port ${port} !`)
);
I am not familiar with the axios as I always use the native fetch API. Maybe the isomorphic fetch can help.
I am writing a nodejs backend application for an application I developed with Vue. I need to create sessions for users' db operations and select databases according to the user. I wanted to use express-session for this, but the sessions I created are seen as undefined in different requests. How can I overcome this problem? I use history mode on Vue so my requests must go through the router for now. Also I can convey that I am open to alternative suggestions.
const express = require('express')
const app = express()
const productRequest = require("./controllers/products/products")
const customerRequest = require("./controllers/customers/customers")
const orderRequest = require("./controllers/orders/orders")
const controllerRequest = require("./controllers/controllers")
const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');
var session = require('express-session')
const cors = require("cors")
app.set('trust proxy', 1) // trust first proxy
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
app.use(express.json());
app.use(cors());
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
app.use('/products', productRequest)
app.use('/orders', orderRequest)
app.use('/customers', customerRequest)
app.use('/controllers', controllerRequest)
module.exports = app;
const express = require('express');
const controllers = express.Router();
const login = require('./login.js')
const userkey = require("./userkey");
controllers.post("/login", (req, res, next) => {
login(req.body, response => {
if (response[0].total == 0) {
res.status(204).json({
message: "Fail",
result: null
})
} else if (response[0].total == 1) {
/* SESSION SETTED HERE */
req.session.corp = response[0].corp
console.log(req.session.corp)
/* HERE SEEMS CREATED */
res.status(200).json({
message: "Connected",
result: response
})
}
})
});
controllers.post("/userkey", (req, res, next) => {
/* CANT USE HERE response UNDEFINED*/
console.log(req.session.corp)
userkey([req.body, req.session.corp], response => {
res.status(200).json({
data: response
})
})
});
module.exports = controllers;
I had some massive headaches with sessions and would have kept going until I read
Also I can convey that I am open to alternative suggestions.
Please then consider using JWT
as simple as this :
var jwt = require('jsonwebtoken');
var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
The jsonwebtoken package is simple to use and should match your needs.
I am new here.
I am trying to develop a web application and I have hit a brick wall which I've been stuck on for a while now.
When running my app.js file all pages show up except for the chatroom. Could someone please take a look at the code and help me out?
I haven't included my code for register and login etc. as they are working fine. When using their router.get and .post concepts for the chatroom I just receive a "Cannot GET /chatroom" message.
Chatroom.js:
const express = require('express');
const router = express.Router();
const socketClient = require('socket.io').listen(4000).sockets;
//Chatroom page: Credit - Traversy Media - https://www.youtube.com/watch?v=hrRue5Rt6Is&t=1542s
router.get('/chatroom', (req, res) => res.render('chatroom.ejs'));
router.post('/chatroom', (req, res) => {
// Connect to Socket.io
socketClient.on('connection', function (socket) {
let chat = db.collection('UsersDB/chats');
// Create function to send status
sendStatus = function (s) {
useUnifiedTopology: true,
socket.emit('status', s);
}
// Get chats from mongo collection
chat.find().limit(100).sort({ _id: 1 }).toArray(function (err, res) {
if (err) {
throw err;
}
// Emit the messages
socket.emit('output', res);
});
// Handle input events
socket.on('input', function (data) {
let name = data.name;
let message = data.message;
// Check for name and message
if (name == '' || message == '') {
// Send error status
sendStatus('Please enter a name and message');
} else {
// Insert message
chat.insert({ name: name, message: message }, function () {
socketClient.emit('output', [data]);
// Send status object
sendStatus({
message: 'Message sent',
clear: true
});
});
}
});
// Handle clear
socket.on('clear', function (data) {
// Remove all chats from collection
chat.remove({}, function () {
// Emit cleared
socket.emit('cleared');
});
});
});
});
app.js:
const express = require('express');
const expressLayouts = require('express-ejs-layouts');
const mongoose = require('mongoose');
const passport = require('passport');
const flash = require('connect-flash');
const session = require('express-session');
const app = express();
// Passport Config
require('./config/passport')(passport);
// DB Config
const db = require('./config/keys').mongoURI;
// Connect to MongoDB
mongoose
.connect(
db,
{ useNewUrlParser: true }
)
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
// EJS
app.use(expressLayouts);
app.set('view engine', 'ejs');
// Express body parser
app.use(express.urlencoded({ extended: true }));
// Express session
app.use(
session({
secret: 'secret',
resave: true,
saveUninitialized: true
})
);
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Connect flash
app.use(flash());
// Global variables
app.use(function(req, res, next) {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
});
// Routes
app.use('/', require('./routes/index.js'));
app.use('/users', require('./routes/users.js'));
app.use('/chatroom', require('./routes/chatroom.js'));
const PORT = process.env.PORT || 5000;
app.listen(PORT, console.log(`Server started on port ${PORT}`));
First and foremost I'd like to thank Cranky Coder; Prakher Londe; and Sunil Lulla for your replies.
I ended up figuring out how to make the chatroom show up. As mentioned before my other pages(login and register etc.) were showing up fine. Unlike the chatroom I had the backend for these in a users.js file. So what I decided to do was move my chatroom.js code into my users.js which was then called in the app.js(the file I run) with app.use('/users', require('.routes/users.js')).
I then changed my router.get code to:
router.get('/chatroom', (req, res) => res.render('chatroom', {
user: req.user
}));
Then in my router.post (see OP for context) I added a res.redirect('/users/chatroom'); before closing with the final bracket.
Lastly I of course edited my .ejs file to have
I found that doing it this way is even better because the chatroom cannot be accessed unless one is logged in.
Thank you again for all your replies and although this is a bit of a specific problem I do hope this helps someone in the future.