I'm trying to get the value of a cookie with a cookie-parser.
The code is as follows (app.js):
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser());
app.get('/', function (req, res) {
console.log('Cookies: ', req.cookies);
});
The log shows the cookies and their value but the page shows the error ERR_EMPTY_RESPONSE
If I do not use this, the web loads perfectly.
I hope you can help me, thanks in advance.
Every middleware function must either invoke the next one in the chain to continue request processing, or finish the response by itself (using res.end() or res.send(...) or similar functions). In your case you're not passing control to next middleware, so response is ending with your function - but you're not properly ending the response either. That's why the error.
If you just want to print cookie value, you can invoke the next middleware in chain by using :
app.get('/', function (req, res, next) {
console.log('Cookies: ', req.cookies);
next(); //--> Added to call next middleware in chain
});
Do you have this at the bottom?
app.listen(8080)
Related
I have an example
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('hello world');
});
In the runtime (for example in 10 sec), I want to stop handling my / endpoint, so when I will make a request, the response would be like Cannot GET /
How can I achieve this behaviour?
You need to create a flag that can be set based on when you want to keep preventing the route from providing the data. Instead of showing Cannot GET /, you should send the status code 503 status code i.e service unavailable.
var express = require('express');
var app = express();
app.get('/', function (req, res) {
if (flag) {
res.status(503).send('Service Unavailable');
} else {
res.send('hello world');
}
});
This could be great if you want to make it for a single route. When you want to control many routes, you can create middleware and use flag similar to the above one.
I was wondering why my router "/posts" is not running or it's just stuck loading its page when I include a middleware of app.use()
const express = require('express');
//Initialize Express
const app = express();
//Middleware
//When I comment this app.use line of code I can access the /posts router but when I left it uncommented
//My localhost sometimes error and keeps on loading
app.use('/posts',()=>{
console.log(' middleware');
});
//Ability to create routes
//ROUTES
app.get("/", (req,res)=>{
res.send('We are on Home page');
});
app.get("/posts", (req,res)=>{
res.send("Welcome back user Ice");
});
//Start Listening to our Server
app.listen(3000);
Based on your code, you're stuck at
app.use('/posts',()=>{
console.log(' middleware');
// You should either call next() here or respond to the HTTP here
})
To understand this, you need to get the concept of middleware in express.
You can imagine middleware like a list of function that a HTTP call should go through, depending on how you arrange it. All middleware registered with express will have access to request object req, the response object res, and the next middleware function. Among the best benefits of middleware pattern is it avoids coupling the sender of a request to the receiver by giving more than one function a chance to handle the request. Both the receiver and the sender have no explicit knowledge of each other.
Types of express middleware
Application level middleware app.use
Router level middleware router.use
Built-in middleware
express.static,express.json,express.urlencoded
Error handling middleware app.use(err,req,res,next)
Thirdparty middleware bodyparser,cookieparser
To better understand why ur code is stucked, lets look at your code again.
const express = require('express');
//Initialize Express
const app = express();
//Middleware
// You registered an application level middleware here, which its route is
// reached via http://localhost:3000/posts
// If you are going to respond here, you should first pass a `req` & `res`
// as a variable to the callback. Then you can just `res.json` `res.send`
// If you want to run some pre-processing of the or checks on the request before
// passing to other middleware, then you should call `next()` when you are done with
// the logic
app.use('/posts',()=>{
console.log(' middleware');
});
//Ability to create routes
//ROUTES
app.get("/", (req,res)=>{
res.send('We are on Home page');
});
app.get("/posts", (req,res)=>{
res.send("Welcome back user Ice");
});
//Start Listening to our Server
app.listen(3000);
If you opt for middleware case (per your question), you need to do this
app.use('/posts',(req,res,next)=>{
console.log(' middleware');
next() // This pass the control to the next middleware registered
});
// Now the request will be passed to this middleware, and runs as you expected
app.get("/posts", (req,res)=>{
res.send("Welcome back user Ice");
});
I want to separate routes from controller.
I tried this approach:
routes/index.js
var express = require('express');
var router = express.Router();
var wordMapperController = require('../controller/wordmapper');
router.get('/', wordMapperController());
module.exports = router;
controller/wordmapper.js
var __construct = function(req, res, next) {
res.render('index', { title: 'Word Mapping for Sanskrit-Indonesian in BG' });
next();
}
module.exports = __construct;
When I start the res is undefined, and prevent the app to be launched.
How does I handle this? How is it app.use and handle router middleware being passed?
The reason why you're getting res is undefined is because you're calling the wordMapperController function and then passing what it returns (in this case undefined, since you don't return anything) as the callback to the router.get method...
This is what you should be doing instead:
routes/index.js
router.get('/', wordMapperController);
Also, there's no reason to call next() in your controller/wordmapper.js file...
From the express.js documentation:
If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.
In your case, you're ending your request-response cycle with the res.render method invocation, therefore you should only be doing this:
controller/wordmapper.js
var __construct = function(req, res, next) {
res.render('index', {
title: 'Word Mapping for Sanskrit-Indonesian in BG'
});
}
You are doing good. But small changes will make your application looks perfect. Find them below.
Change the line "router.get('/', wordMapperController())" to
"router.get('/', wordMapperController)" - because when hits the route "/", it
will calls the middle ware function in the controller by passing request, response
and next as parameters;
If you want to render a template, you have to set the template engine server file -
for eg: app.set('view engine', 'pug') (if it is a .pug file);
Let me know if you get any issues while doing the above.
For reference, You can go through this link - https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/routes
Thank you.
the code below works:
var express = require('express');
var path = require('path');
var app = express();
app.use('/public', express.static("./public"));
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
But if I change the app.use like this:
var express = require('express');
var path = require('path');
var app = express();
app.use('/public', function(){express.static("./public")});
// browser error "cannot GET /
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
Why? The server doesn't seem to catch any errors
express.static() returns a middleware function when you call it. You have to pass that specific returned function to app.use(). You don't just call express.static() on every request. You call it once, get the returned function and register that as middleware and app.use() will then call that middleware function on every request.
When you do it the correct way like this:
app.use('/public', express.static("./public"));
It's like doing this:
const fn = express.static("./public");
app.use('/public', fn);
or even like this:
const fn = express.static("./public");
app.use('/public', function(req, res, next) {
fn(req, res, next);
});
Hopefully you can see that this code:
app.use('/public', function(){express.static("./public")});
does not do the same thing as any of the correct solutions. This calls express.static() in every request and never calls the returned function that does the actual work for a given request.
Think of express.static("./public") like a factory function. It creates a middleware function that you then pass to app.use() or call yourself with req, res and next as the arguments.
Why? The server doesn't seem to catch any errors
Executing app.use('/public', function(){express.static("./public")}); is not what you want, but it also doesn't create an error. All it does is create a new middleware function (which you ignore) on every single request. It also never calls next to let any other request handlers handle the request so your server would get stuck on every request, but it never actually causes a visible error.
It essentially becomes functionally equivalent to this:
app.use('/public', function(req, res, next) {
// do nothing, just causes the request to get stuck since
// the request is not handled (no response is sent)
// and next is never called
});
The request is never handled and never calls next to advance to other route handlers so the request just gets stuck and will eventually time out.
You can try with:
app.use(express.static(path.resolve(__dirname, './public'), { maxAge: '1d' }));
i just want to try basic methods to set cookie and show in request head.
front-end is just a basic html form with username and password text input, use POST method to transfer data.
below is code based on express.
server just receive req.body, then set it as cookie with domain: localhost:1338/base
cookieRouter.js:
var express = require('express');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var router = express.Router();
router.use(bodyParser.urlencoded({ extended: false }));
router.use(cookieParser());
router.get('/', function (req, res) {
res.send('this is a router base page!');
});
router.get('/index1.html', function (req, res) {
res.sendFile(__dirname + '/index1.html');
});
router.post('/index1.html', function (req, res) {
res.cookie('name', req.body, { domain: 'localhost:1338', path: '/base' });
res.send(req.body);
});
module.exports = router;
app.js
var express = require('express');
var app = express();
var cookieRouter = require('./cookieRouter.js');
app.get('/', function (req, res) {
res.send('this is home page!');
});
app.use('/base', cookieRouter);
app.listen(1338);
after run app.js, request header has set-cookie value obviously. but can't get it into request header, and req.cookies is empty object {}, even after refreshing the web.
but if i just use simplest demo, it can work, for instance:
router.get('/', function (req, res) {
res.cookie('name', 'test');
});
one more thing, i feel the trouble with express is that only one res.send(), res.redirect()... can be sent as by default it will add head automatically, otherwise, it will come up with error: Can't set headers after they are sent.
someone said add return can solve this problem, but i failed, so want to how how to add, can anyone give an complete demo?
The cookie is missing because the domain attribute is incorrect -- 'localhost:1338' need to be changed to 'localhost'. Port information should not be included in domain.
Yes, according to the Network panel of browser dev tool, there is a Set-Cookie response header (as the screenshot displayed). However, if you check Application - Cookies panel in Chrome (or corresponding panel in other browsers), you will find that: the cookie specified by Set-Cookie header is not there. Browser does not store it and won't send it in the following HTTP requests.
Also, please note that as the cookie's path is /base, only the HTTP requests whose URL starts with /base can send the cookie.