Set custom header when using res.render - node.js

I'm using express.js's res.render function and I met some issue to set custom headers, I'm tried 4 kind of method and all failed
here is my code
Method 1
app.get('/login', function(req, res, next) {
res.writeHead(200, {'Content-Type':'text/plain; charset=utf-8'});
next()
});
app.get('/login', function(req, res) {
res.locals.text="hello";
res.render('index');
});
It has a error log with this code: Error: Can't set headers after they are sent.
Method 2 (example from here)
app.get('/login', function(req, res, next) {
res.header(200, {'Content-Type':'text/plain; charset=utf-8'});
next()
});
app.get('/login', function(req, res) {
res.locals.text="hello";
res.render('index');
});
the code comes with the error: TypeError: field.toLowerCase is not a function
Method 3
app.get('/login', function(req, res) {
res.writeHead(200, {'Content-Type': 'application/xhtml+xml; charset=utf-8'});
res.locals.text="hello";
res.render('index');
});
the code also has error: Error: Can't set headers after they are sent.
That's all the ways I can thought and find but still can't resolve, is there any ways to set custom header (especially encoding type) with res.render?

To set custom response header with res.render, you can use res.set(). Here is an example code:
app.get('/login', function(req, res) {
res.set({'Content-Type': 'application/xhtml+xml; charset=utf-8'});
res.locals.text="hello";
res.render('index');
});
Please check Express document for more details about res.set()

If you want to set an header for your response, you can use setHeader method on http.ServerResponse object.
var server = require('http').createServer(function(req, res) {
res.setHeader('content-type', 'application/json');
res.write(headerStr);
res.end();
});

Related

Using express middleware only for a GET request

The way I understand it, if I do something like:
app.use('/something', function(req, res, next) {
// some content here
});
This basically means that if there's a request to 'something', then the middleware (my function) is executed before the next function.
So if I have something like this to handle a GET request,
app.get('/something', function(req, res, next) {
console.log('hello');
});
Then 'hello' is going to be printed out after my original function has finished executing.
But how do I make it so that my middleware function is just executed when I ONLY make a GET request and not a POST request?
For a GET only middleware, just do the following
// Get middleware
app.get('/something', function(req, res, next) {
console.log('get hello middleware');
next();
});
// GET request handler
app.get('/something', function(req, res) {
console.log('get hello');
res.end();
});
// POST request handler
app.post('/something', function(req, res) {
console.log('post hello');
res.end();
});
app.post('/something', your_middleware, function(req, res, next) {
console.log('hello');
});
Only during the post request your_middleware will be executed.
your_middleware should be a function as follows:
function(req, res, next){
....
next()
}
you can pipe in as many middlewares you want in this way for a specific route and request type

How do I automatically return a 404 when a GET path doesn't exist?

I am using NodeJS, Express and Handlebars (template engine) to build a web application. Currently I'm trying to automatically redirect users whenever they enter an URL that does not exist (or whenever they might not have access to it).
The following returns the index page:
router.get('/', (req, res) => {
res.render('index/index');
});
But how do I make something like this:
router.get('/:ThisCouldBeAnything', (req, res) => {
res.render('errors/404');
});
The following example is from Github:
Say that I enter this URL:
https://github.com/thispagedoesnotexist
It automatically returns a 404. How do I implement this in my application?
Thanks in advance.
Use a middleware just after all route handlers to catch non existing routes:
app.get('/some/route', function (req, res) {
...
});
app.post('/some/other/route', function (req, res) {
...
});
...
// middleware to catch non-existing routes
app.use( function(req, res, next) {
// you can do what ever you want here
// for example rendering a page with '404 Not Found'
res.status(404)
res.render('error', { error: 'Not Found'});
});
After all your other routes you can add:
app.get('*', (req, res) => {
res.render('errors/404');
});
Alternately, you can use a middleware function after all your other middleware and routes.
app.use((req, res) => {
res.render('errors/404');
});
So you might end up with something that looks like:
//body-parser, cookie-parser, and other middleware etc up here
//routes
app.get('/route1', (req, res) => {
res.render('route1');
});
app.get('/route2', (req, res) => {
res.render('route2');
});
//404 handling as absolute last thing
//You can use middleware
app.use((req, res) => {
res.render('errors/404');
});
//Or a catch-all route
app.get('*', (req, res) => {
res.render('errors/404');
});
I see that you have express tagged. All you have to do is include a default handler that includes
res.status(404).render('404template')
For example
app.get('*', (req, res,next) => {
res.status(404).render('error.ejs')
});

Get HTTP version of incoming request

How can I extract the HTTP version of an incoming request using express?
I need something like:
app.use('/', (req, res, next) => {
req.getHttpVersion() // 'HTTP 1.0'/'HTTP 1.1'/'HTTP 2.0'
});
Try this:
app.use('/', (req, res, next) => {
console.log('Request HTTP Version: ', req.httpVersion)
});
I know tis is old , but still..
you can try :
app.use('/', (req, res, next) => {
console.log('AlpnProtocol: ' , req.connection.alpnProtocol,)
});

how to group api in express

Here is the example:
var app = require('express')();
function validateToken(req, res, next) {
// Do something with request here
next();
};
app.get('/user/login', function(req, res) {
//code
});
app.post('/user/register', function(req, res) {
//code
})
app.put('/user/register', validateToken, function(req, res) {
//code
})
app.delete('/user/delete', validateToken, function(req, res) {
//code
})
If I have 10 api that need validToken, I should add validToken middleware 10 times, like:
app.method('......', validateToken, function(req, res) {
//code
})
app.method('......', validateToken, function(req, res) {
//code
})
....
app.method('......', validateToken, function(req, res) {
//code
})
app.method('......', validateToken, function(req, res) {
//code
})
How can I group api by using the same middleware?
Here's how to re-use the same callback function for multiple routes (like middleware):
var app = require('express')();
function validateToken(req, res, next) {
// Do something with request here
next();
};
app.get('/user/login', function(req, res) {
// code
});
app.post('/user/register', function(req, res) {
// code
});
// Be sure to specify the 'next' object when using more than one callback function.
app.put('/user/register', validateToken, function(req, res, next) {
// code
next();
});
app.delete('/user/delete', validateToken, function(req, res, next) {
// code
next();
});
Also, you can replace app.METHOD (e.g. .post, .get, .put, etc.) with app.all and your callback will be executed for any request type.
Just wrong, so do not put into mass participation of the (Google translated from: 刚才看错了,改成这样就不用放进传参了)
var group = {url:true,url:true,url:true};
app.use(function(req,res,next){
if(group[req.url]){
// Do something with request here
next();
} else {
next();
}
})

What is ending a route

Supose i have this route code:
app.get('/', function(req, res) {
res.send('Hello world!');
});
app.get('/something', function(req, res) {
// Do something
});
If i visit the / route in my browser, the "Hello world" message will show, and my response will have ended.
Question: Is it the absence of next() in this router, or the res.send() that ENDS the http request?
It's res.end() that actually ends the response, but res.send() calls this.
You can see this in the source here.
Sorry, but if you want to log every request including '/' then you have to reorder using:
app.use(function(req, res, next) {
// log each request to the console
console.log(req.method, req.url);
// continue doing what we were doing and go to the route
next();
});
app.get('/', function(req, res) {
res.send('Hello world!');
});

Resources