Nuxt serverMiddleware always return 200 code - vue.js

I'm trying to handle request errors on the ssr side, for this I use serverMiddleware, but the problem is that res.statusCode is always 200. Although in the browser I see the page crashed with 500 code. Feeling as if the middleware fires before my api requests. Is there any way to solve this problem?
server-middleware/logger.js
export default function (req, res, next) {
console.log('Server middleware', res.statusCode);
next()
}
nuxt.config.js
serverMiddleware: ['~/server-middleware/logger'],

Related

Why does the use() method still executed after get() has handled a request successfully in express.js?

I have this express.js code:
app.get('/', (req, res) => {
res.render('homePage', { title: 'Express' });
});
app.use((req, res) => {
console.log('use() is executed');
res.end();
});
If the request is handled by the get() method, use() is not supposed to execute. But I noticed that it still execute even though everything was fine and the page is rendered. Did I do something wrong or did I miss something? Thanks.
From Express Doc:
Link: http://expressjs.com/en/4x/api.html#app.use
app.use([path,] callback [, callback...])
Mounts the specified middleware function or functions at the specified path: the middleware function is executed when the base of the requested path matches the path.
app.use() register the function as middleware, and you didn't specify the path. That's why it will run every time when any route is called.
The placement of the middlewares will change the execution order. However, they don't change the fact that the middleware will be executed as, well middlewares, which will be executed before the actual functions with in the routes.

express api responds to GET and POST but not PUT and DELETE through cors but responds properly when the request is local

When I'm sending a request to my express API through Axios, the GET and POST request respond correctly, but PUT and DELETE does not.
This is not a code problem as all my tests are passing, I believe this is related to CORS
I have installed morgan npm package to log the requests to the server.
The GET and POST are working fine, but PUT/DELETE are not and console.log() messages in those route handlers don't even show up!!!
The response from PUT and DELETE is 404
app.js
app.use(cors())
router.js
router.delete('/', (req, res) => {
// this log statement does not show up!
console.log('request recieved')
Controller.DeleteItem(req.body.data.title).then(() => {
res.redirect('/')
}
}
console output
OPTIONS 204
DELETE 404
request
axios.delete('http://localhost:5000/', {
data: {
title: title
}
}
This was discussed outside SO : the issue was that the put and delete routes were placed inside the post route, the indentation (not appearing here) was obvious when seeing the whole code in context.

VueRouter make HTTP request within beforeEach

I am attempting to make an AXIOS request within router.beforeEach. However, it looks like the request is being made with my next destination URL being prepended; if trying to access /client/create, the beforeEach appears to prepend '/client/create' to the request.
Instead of '/api/participant/test/{some_id}' the request is being sent to '/client/create/api/participant/{some_id}'.
I'm not quite sure why this is happening. The documentation indicates that you could use a getPost() method to make requests:
beforeRouteEnter (to, from, next) {
getPost(to.params.id, (err, post) => {
next(vm => vm.setData(err, post))
})
},
However it seems the getPost() method is unrecognized, which could be because of the beforeEach call (the documentation does not show that this could be used with this particular method).
Here is the code with the AXIOS request.
router.beforeEach((to, from, next) => {
console.log(to.params.id);
// Check to see if the cookie exists
if (document.cookie.match(/^(.*;)?\s*participant_token\s*=\s*[^;]+(.*)?$/)) {
axios.get('api/participant/test/' + to.params.id)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
}
Any ideas on how this can be avoided? I imagine one could use beforeRouteEnter for each of the routes I have set up, but this would be a more elegant solution.
It should be
axios.get('/api/participant/test/' + to.params.id)
(with forward slash character at the beginner).
The more properly way to set baseURL in axios config
For example:
axios.defaults.baseURL = 'your base url';
First, there is no built-in getPost method in Vue.js. Documentation has mentioned it just as an illustration purpose.
Also, use root relative URL instead of relative URL that you are trying to use.
axios.get('/api/participant/test/' + to.params.id)
You are trying to use relative URL which is causing a problem for you. The more generic way would be to set default base URL in Axios global config.

res.render for routes on page reload?

(Using MEAN with UI Router)
The following code sends a json response for the route defined. This works fine when the template is rendered with UI Router; however, if I reload the page, because the response only contains json, I am left with an empty page rendering no html, only the json response.
router.get('/posts/:post', function(req, res, next) {
req.post.populate('comments', function(err, post) {
if (err) { return next(err); }
res.json(post);
});
});
Assuming this is a standard issue, how can I best allow this page to res.render('index') when the page is reloaded and respond with the json response? Should I,
Create a separate route for the json response which is called as a post promise with UI Router
Have the /posts/:post route simply respond with res.render('index')?
Thank you for any responses, not sure what the usual practise is for such issues!
It took me a while to find a working solution to this due to many of the examples online having different directory structures. I placed a catch all at the end of my routes so that url requests to any UI Router states would not be met with a 404, but instead always return the index.html file.
app.all('/*', function(req, res, next) {
// Just send the index.html for other files to support HTML5Mode
res.sendFile('index.html', { root: __dirname });
});
Then I added prefixes to my express routes, e.g. /api/posts/:post etc. Apparently express routes should not clash with any of the angular defined routes. Thanks to NormySan on reddit for informing me about this.

Express handling CSRF error

How can I implement a custom error handler in Express using CSRF middleware after users click the back button in browser and resubmit the form? By default Express return a 403 page with lots of stack traces. I want to replace it by for example redirecting user to a custom error page. How can I do that?
Here are some examples of writing custom error handlers in Express: https://github.com/visionmedia/express/blob/master/examples/error-pages/index.js
Here are the custom error handlers I use: Error handling in an Express route
You might also want to consider modifying connect to return a different code than 403 when CSRF fails. You can change it here: https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js#L82
You might choose 428 Precondition Required. The full list is here: http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
That way, you could have a special message shown only for CSRF failures.
Like any other well designed middleware csurf passes the error to next. So it's possible to react on the raised error in the following way:
var csurf = require('csurf')();
app.use(function (req, res, next) {
csurf(req, res, function (err) {
if (err) {
// do what ever with err
} else {
next();
}
});
});