I'm trying to using express().router as middleware for express server.
this is the code for the express server -
const server = express();
const port = process.env.PORT || 5000;
server.use(logger("short"));
server.use(respomnseTime(4)) // The number indicate how digits we want
server.use('/', mRouter);
server.use((request, response, next)=>{
mUtil.print("Request IP: " + request.url);
mUtil.print("Request Date: " + new Date());
next();
})
server.use((request, response, next)=>{
mUtil.auth(request, response, next);
})
server.use((request, response, next)=>{
console.log("Middleware 2");
next();
})
this is the code for the router (another file) -
const router = require('express').Router();
router.get('/', (request, response) => {
response.send({ express: 'YOUR EXPRESS BACKEND IS CONNECTED' });
});
router.get('/user/:username', (request, response)=>{
});
router.get('/about', (request, response)=>{
});
router.get('/contact', (request, response)=>{
});
It looks like he middlewares after -
server.use('/', mRouter);
not running. I thought the problem happens because there is no call to next() function, but I'm not sure how to write it. Anyone have an idea?
you should export your router like below
module.exports = router;
Related
I am using ec2(nodejs+express+webpack)-cloudflare setup and my bundle size is only about 100kb.
But the problem is that the 100kb bundle takes way too long(25~30secs)
I think it is a problem in my express or nodejs setting since index.html[1kb] also takes 700ms and favicon[2kb] takes 1.91s to load.
I'm wondering if this is because ec2 freetier is slow or is it my setting that's keeping it so slow.
I use
1 cloudflare ssl for https connection
2 iptables prerouting from 80 to 3000(my node env)
3 express server with main page like this
const app = express();
const port = process.env.p || 3000;
app.get('/', function (request, response){
response.sendFile(path.resolve('public', 'index.html'), 'utf8');
});
app.use('/css', express.static('css'));
app.use('/static', express.static('static'));
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: true }));
app.use(bodyParser.json());
app.post('/signup', (req, res) =>{
signup(req.body, res);
});
app.post('/login', (req, res) =>{
login(req.body, res);
});
app.get('/userlist', (req, res)=>{
ulist(req.query, res);
});
app.get('/atoc', (req, res)=>{
console.log(req.query);
atocf(req.query, res);
});
app.get('/data/allshops', (req, res)=>{
allshops(res);
});
app.get('/manager/checkurl', (req,res)=>{
checkurl(req.query, res);
});
app.post('/manager/upload', upload.single('file'),(req,res)=>{
s3u(req.file,req.body, res);
})
app.post('/manager/addshop', (req,res)=>{
addshop(req.body, res);
});
app.post('/manager/editshop', (req,res)=>{
editshop(req.body, res);
});
app.post('/manager/shop', (req,res)=>{
mshopdata(req.body, res);
});
app.post('/manager/shops', (req,res)=>{
myshops(req.body, res);
});
app.post('/manager/pub', (req,res)=>{
msetpublic(req.body, res);
});
app.post('/manager/rm', (req,res)=>{
msetrm(req.body, res);
});
app.post('/data/shop', (req,res)=>{
if(req.body._url==undefined||req.body._url==''){
res.send("{'ic_error':'NO_URL'}");
}
else
shopdata(req.body, res);
});
app.get('*', function (request, response){
const paths = request.path.split('/');
if(nofollow.includes(paths[1])){
response.sendFile(path.resolve('public', 'index.html'), 'utf8');
return;
}
if(keypaths.includes(paths[1])){
response.sendFile(path.resolve('public', paths[1]+'.html'),'utf8');
return;
}
//shopmetadata({_url: decodeURIComponent(paths[1])}, response);
sendpage({_url: decodeURIComponent(paths[1])},response)
});
const server = app.listen(port, () => {
console.log('Express listening on port', port);
});
What may I be doing wrong that is slowing down the traffic so hard?
thanks in advance!
I am using express backend with a react frontend everything is working fine but occasionally i get error
Cant set header after they are sent
and server gets down.i searched few ways this error might happen but in my code i could not find such cases.i tried to be simple as possible in the code.can anyone please point me what might be the issue?
Server.js file
// call the packages we need
const addItem = require('./controllers/addItem');
const addCategory = require('./controllers/addCategory');
const addSubCategory = require('./controllers/addSubCategory');
const getSubCategory = require('./controllers/getSubCategoryByCategory');
const getCategory = require('./controllers/getAllCategory');
const getAllItems = require('./controllers/getAllItems');
const cors = require('cors');
const express = require('express');
// call express
const app = express(); // define our app using express
const bodyParser = require('body-parser');
// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
const port = process.env.PORT || 8080; // set our port
// ROUTES FOR OUR API
// =============================================================================
const addItemRoute = express.Router(); // get an instance of the express Router
const getCategoryRoute = express.Router();
const addCategoryRoute = express.Router();
const addSubCategoryRoute = express.Router();
const getSubCategoryRoute = express.Router();
const getAllItemsRoute = express.Router();
getCategoryRoute.get('/get_category', (req, res) => {
getCategory(res);
});
addCategoryRoute.post('/add_category', (req, res) => {
addCategory(req.body.name, res);
});
getSubCategoryRoute.get('/get_subcategory/:catId', (req, res) => {
getSubCategory(req.params.catId, res);
});
addSubCategoryRoute.post('/add_subcategory', (req, res) => {
addSubCategory(req.body.name, req.body.cat_id, res);
});
// code, name, quantity, length, description and subcategory id should be passed as parameters
addItemRoute.post('/add_item', (req, res) => {
addItem(req.body.item, res);
});
getAllItemsRoute.get('/get_items', (req, res) => {
getAllItems(res);
});
// more routes for our API will happen here
// REGISTER OUR ROUTES -------------------------------
// all of our routes will be prefixed with /api
app.use('/api', addItemRoute);
app.use('/api', getCategoryRoute);
app.use('/api', addCategoryRoute);
app.use('/api', addSubCategoryRoute);
app.use('/api', getSubCategoryRoute);
app.use('/api', getAllItemsRoute);
// START THE SERVER
// =============================================================================
app.listen(port);
console.log(`Server started on port ${port}`);
getAllCategories() function
Object.defineProperty(exports, '__esModule', {
value: true,
});
const pool = require('./connection');
module.exports = function (res) {
pool.getConnection((err, connection) => {
if (err) {
connection.release();
return res.json({ code: 100, status: 'Error in connection database' });
}
console.log(`connected as id ${connection.threadId}`);
connection.query('select * from category;', (err, rows) => {
connection.release();
if (!err) {
return res.json(rows);
}
});
connection.on('error', err => res.json({ code: 100, status: 'Error in connection database' }));
});
};
If you get an error in connection.query() you send a response with res.json(). This error is caught in connection.on('error') where you send another response. You can't send two responses to the same request. It seems that in this case, you don't really need connection.on() at all or if you have it to catch other errors, don't send a response on connection.query()'s error.
I am new to node and express. I have seen app.get and app.post examples using both "res.send" and "return res.send". Are these the same?
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.type('text/plain');
res.send('i am a beautiful butterfly');
});
or
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.type('text/plain');
return res.send('i am a beautiful butterfly');
});
The return keyword returns from your function, thus ending its execution. This means that any lines of code after it will not be executed.
In some circumstances, you may want to use res.send and then do other stuff.
app.get('/', function(req, res) {
res.send('i am a beautiful butterfly');
console.log("this gets executed");
});
app.get('/', function(req, res) {
return res.send('i am a beautiful butterfly');
console.log("this does NOT get executed");
});
I would like to point out where it exactly made a difference in my code.
I have a middleware which authenticates a token. The code is as follows:
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1] || null;
if(token === null) return res.sendStatus(401); // MARKED 1
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
if(err) return res.sendStatus(403); // MARKED 2
req.user = user;
next();
});
}
On the // MARKED 1 line, if I did not write return, the middleware would proceed and call next() and send out a response with status of 200 instead which was not the intended behaviour.
The same goes for like // MARKED 2
If you do not use return inside those if blocks, make sure you are using the else block where next() gets called.
Hope this helps in understanding the concept and avoiding bugs right from the beginning.
app.get('/', function(req, res) {
res.type('text/plain');
if (someTruthyConditinal) {
return res.send(':)');
}
// The execution will never get here
console.log('Some error might be happening :(');
});
app.get('/', function(req, res) {
res.type('text/plain');
if (someTruthyConditinal) {
res.send(':)');
}
// The execution will get here
console.log('Some error might be happening :(');
});
To Add a little bit more context to the examples above. Express has layers. So if you return in your function you end the execution. If you not end that you can go further in your layered logic.
So the next function passed to each layer can be called to execute the next layer. If you don't call next the execution stops after your method excuted is executed. (Return just exits the function)
The response object is still available after sending. It is just not possible to write to it again because it has already completed after you did res.end() or res.send().
const express = require('express');
const app = express();
const port = process.env.PORT || 5000;
// a controller handles a http request and terminat it
const controller = (req, res, next) => {
// return http response to client
res.send('hello world');
// do something after you sended request
console.log('do something else');
// if you call next the request will go to the next layer -> afterSend,
// if you do not call next the execution will end
next();
};
// this middleware/layer is executed after response is send to client
const afterSend = (req, res, next) => {
// do something after you sended request, but not send again -> readonly
console.log(res);
// this would throw an error
// res.send()
// res.end()
// etc...
};
// we skip routers here
app.get('/hello', controller, afterSend);
app.listen(port, () => {
console.log(`Running on ports ${port}`);
});
Following is my server file. I am making 2 calls, one post and one get. It works fine at times. But gives an error of : Can't set headers after they are sent. Does this have anything to do with my client side code?
server.js
var express = require('express')
var mongoose = require('mongoose')
var path = require('path')
var bodyParser = require("body-parser")
var cors = require("cors")
var app = express()
var port = process.env.PORT || 3000
var Url = require("./data/url-schema");
//Express request pipeline
app.use(express.static(path.join(__dirname,"../client")))
app.use(bodyParser.json())
app.use(cors());
/*
Your server must be ready to handle real URLs. When the app first loads at / it will probably work, but as the user navigates around and then hits refresh at /dashboard your web server will get a request to /dashboard. You will need it to handle that URL and include your JavaScript application in the response.
*/
app.get('*', function (request, response, next){
response.sendFile(path.resolve(__dirname, '../client', 'index.html'))
next()
})
app.get('/:code', function(req, res) {
console.log("reg", req.params.code)
Url.findOne({code:req.params.code}, function(err, data){
console.log("data", data)
if(data)
res.redirect(302, data.longUrl)
else
res.end()
})
})
app.post('/addUrl', function (req, res, next) {
console.log("on create");
Url.findOne({longUrl:req.body.longUrl}, function(err, data) {
if (err)
res.send(err);
else if(data) {
console.log("already exists",data)
res.send("http://localhost:3000/"+data.code);
} else {
var url = new Url({
code : Utility.randomString(6,"abcdefghijklm"),
longUrl : req.body.longUrl
});
console.log("in last else data created",url)
url.save(function (err, data) {
console.log(data)
if (err)
res.send(err);
else
res.send("http://localhost:3000/"+data.code);
});
}
});
})
app.listen(port, function () {
console.log('Example app listening on port 3000!')
});
// Connect to our mongo database
mongoose.connect('mongodb://localhost/shortUrl');
I get the Following error
error
_http_outgoing.js:335
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (/opt/lampp/htdocs/url-shortener/node_modules/express/lib/response.js:718:10)
at ServerResponse.location (/opt/lampp/htdocs/url-shortener/node_modules/express/lib/response.js:835:8)
at ServerResponse.redirect (/opt/lampp/htdocs/url-shortener/node_modules/express/lib/response.js:874:8)
at Query.<anonymous> (/opt/lampp/htdocs/url-shortener/server/server.js:30:8)
at /opt/lampp/htdocs/url-shortener/node_modules/mongoose/node_modules/kareem/index.js:177:19
at /opt/lampp/htdocs/url-shortener/node_modules/mongoose/node_modules/kareem/index.js:109:16
at process._tickCallback (node.js:355:11)
From the execution order, in * route handler, the body is being assigned to the response and then in /:code, the response code 302 is being added, where Location header is also added, hence the error. Any header must be added before the body to the response.
To solve this problem, simply change the order of the two GET statements.
Finally found the solution:
var express = require('express')
var mongoose = require('mongoose')
var path = require('path')
var bodyParser = require("body-parser")
var app = express()
var port = process.env.PORT || 3000
var Url = require("./data/url-schema")
var Utility = require("./utility")
//Express request pipeline
app.use(express.static(path.join(__dirname,"../client")))
app.use(bodyParser.json())
/*
Your server must be ready to handle real URLs. When the app first loads at / it will probably work, but as the user navigates around and then hits refresh at /dashboard your web server will get a request to /dashboard. You will need it to handle that URL and include your JavaScript application in the response.
*/
app.get('/dashboard', function (request, response, next){
response.sendFile(path.resolve(__dirname, '../client', 'index.html'))
next()
})
app.get('/about', function (request, response, next){
response.sendFile(path.resolve(__dirname, '../client', 'index.html'))
next()
})
app.get('/:code', function(req, res) {
Url.findOne({code:req.params.code}, function(err, data){
if(data){
res.redirect(302, data.longUrl)
}
})
})
app.post('/addUrl', function (req, res, next) {
Url.findOne({longUrl:req.body.longUrl}, function(err, data) {
if (err){
res.send(err)
}
else if(data) {
res.send("http://localhost:3000/"+data.code);
} else {
var newCode = getCode()
checkCode(newCode)
.then(function(data){
var url = new Url({
code : data,
longUrl : req.body.longUrl
});
url.save(function (err, data) {
if (err)
res.send(err);
else
res.send("http://localhost:3000/"+data.code);
});
})
}
});
})
app.listen(port, function () {
console.log('Example app listening on port 3000!')
});
// Connect to our mongo database
mongoose.connect('mongodb://localhost/shortUrl');
//Generate a random code
function getCode() {
return Utility.randomString(6,"abcdefghijklmnopqrstuvwxyz")
}
//Check if the code is unique
function checkCode(code) {
return new Promise(function (resolve, reject){
Url.findOne({code:code}, function(err, data) {
if(err === null){
resolve(code)
}else if(data){
saveUrlCode(getCode())
}
})
})
}
My earlier route which was :
app.get('*', function (request, response, next){
response.sendFile(path.resolve(__dirname, '../client', 'index.html'))
next()
})
The get route was getting executed twice on account of the above call and the
app.get(":/code") call.
So I had to handle the routes properly which I have done by handling the dashboard and about routes separately instead of using the "*" route.
At the moment I have the following which sits below all my other routes:
app.get('*', function(req, res){
console.log('404ing');
res.render('404');
});
And according to the logs, it is being fired even when the route is being matched above. How can I get it to only fire when nothing is matched?
You just need to put it at the end of all route.
Take a look at the second example of Passing Route Control:
var express = require('express')
, app = express.createServer();
var users = [{ name: 'tj' }];
app.all('/user/:id/:op?', function(req, res, next){
req.user = users[req.params.id];
if (req.user) {
next();
} else {
next(new Error('cannot find user ' + req.params.id));
}
});
app.get('/user/:id', function(req, res){
res.send('viewing ' + req.user.name);
});
app.get('/user/:id/edit', function(req, res){
res.send('editing ' + req.user.name);
});
app.put('/user/:id', function(req, res){
res.send('updating ' + req.user.name);
});
app.get('*', function(req, res){
res.send('what???', 404);
});
app.listen(3000);
Alternatively you can do nothing because all route which does not match will produce a 404. Then you can use this code to display the right template:
app.error(function(err, req, res, next){
if (err instanceof NotFound) {
res.render('404.jade');
} else {
next(err);
}
});
It's documented in Error Handling.
I bet your browser is following up with a request for the favicon. That is why you are seeing the 404 in your logs after the 200 success for the requested page.
Setup a favicon route.
You can this at the end of all routes,
const express = require('express');
const app = express();
const port = 8080;
// All your routes and middleware here.....
app.use((req, res, next) => {
res.status(404).json({
message: 'Ohh you are lost, read the API documentation to find your way back home :)'
})
})
// Init the server here,
app.listen( port, () => {
console.log('Sever is up')
})
Hope it helpful, I used this code in bottom of routes
router.use((req, res, next) => {
next({
status: 404,
message: 'Not Found',
});
});
router.use((err, req, res, next) => {
if (err.status === 404) {
return res.status(400).render('404');
}
if (err.status === 500) {
return res.status(500).render('500');
}
next();
});
You can use this
const express = require('express');
const app=express();
app.set('view engine', 'pug');
app.get('/', (req,res,next)=>{
res.render('home');
});
app.use( (req,res,next)=>{
res.render('404');
})
app.listen(3000);
I wanted a catch all that would render my 404 page only on missing routes and found it here in the error handling docs https://expressjs.com/en/guide/error-handling.html
app.use(function (err, req, res, next) {
console.error(err.stack)
res.status(404).render('404.ejs')
})
This worked for me.
Very simple you can add this middleware.
app.use(function (req, res, next) {
//Capture All 404 errors
res.status(404).render("404.ejs")
})
404 error in a service is typically used to denote that the requested resource is not available. In this article we will see how to handle 404 error in express.
We need to handle the Error and Not-Found collectively as
Write two separate middleware for each,
// Import necessary modules
const express = require('express');
// Create a new Express app
const app = express();
// Define routes and middleware functions
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Catch 404 Not Found errors and forward to error handler
app.use((req, res, next) => {
const error = new Error('Not Found');
error.status = 404;
next(error);
});
// Error handler middleware function
app.use((err, req, res, next) => {
// Set status code and error message based on error object
res.status(err.status || 500);
res.send({
error: {
message: err.message
}
});
});
// Start the server
app.listen(3000, () => {
console.log('Server started on port 3000');
});