代码区项目交易流程

node.js middleware and js encapsulation


I'm new to javascript, and jumped right into node.js . I've read a lot of theory, and began well with the practical side (I'm writing an API for a mobile app), but I have one basic problem, which has lead me to middleware. I've successfully implemented a middleware function, but I would like to know if the use I'm giving the idea of middleware is OK, and also resolve the original problem which brought me to middleware. My question is two-fold, it's as follows:

1) From what I could gather, the idea of using middleware is repeating a process before actually processing the request. I've used it for token verification, as follows: Only one of my urls doesn't receive a token parameter, so

app.js

app.get('/settings', auth.validateToken, auth.settings);

auth.js

function validateToken(req, res, next){ //code };

In validateToken, my code checks the token, then calls next() if everything is OK, or modifies res as json to return a specific error code.

My questions regarding this are: a) Is this a correct use of middleware? b) is there a [correct] way of passing a value onto the next function? Instead of calling next only if everything is OK, is there a [correct] way of calling next either way, and knowing from inside the next function (whichever it is), if the middleware was succesful or not? If there is, would this be a proper use of middleware? This precise point brings me to my original problem, and part two of this question, which is encapsulating functions:

THIS PART WAS FIXED, SEE MY SECOND COMMENT .

2) I discovered middleware trying to simply encapsulate validateToken, and be able to call it from inside the functions that the get handlers point to, for example auth.settings. I'm used to common, sequential programming, and not in javascript, and haven't for the life of me been able to understand how to do this, taking into account the event-based nature of node.js .

What I want to do right now is write a function which simply verifies the user and password. I have it perfectly written inside a particular handler, but was about to copy-paste it to another one, so I stopped. I want to do things the right way from scratch, and understand node.js . One of the specific problems I've been having, is that the error code I have to return when user and password don't match are different depending on the parent function, so I would need this function to be able to tell the callback function "hey, the password and user don't match", so from the parent function I can respond with the correct message.

I think what I actually want is to write an asynchronous function I can call from inside another one.

I hope I've been clear, I've been trying to solve this on my own, but I can't quite finish wrapping my head around what my actual problem is, I'm guessing it's due to my recent introduction to node.js and JS. Thanks in advance! Jennifer.

Problem courtesy of: shinax

Solution

1) There is res.locals object ( http://expressjs.com/api.html#res.locals ) designed to store data local to the request and to pass them from one middleware to another. After request is processed this object is disposed of. If you want to store data within the session you can use req.session.

2) If I understand your question, you want a function asynchronously passing the response to the caller. You can do it in the same way most node's functions are designed.

You define a function in this way:

function doSomething(parameters, callback) { // ... do something // if (errorConddition()) err = errorCode(); if (callback) callback(err, result) }

And the caller instead of using the return value of the function passes callback to this function:

function caller(req, res, next) { //... doSomething(params, function(err, result) { if (! err && result) { // do something with the result next(); } else { // do something else next(); // or even res.redirect('/error'); } }); }

If you find yourself writing similar callback functions you should define them as function and just pass the function as parameter:

//... doSomething(param, processIt); function processIt(err, result) { // ... }

What keeps you confused, probably, is that you don't treat functions as values yet, which is a very specific to JavaScript (not counting for languages that are little used).

Solution courtesy of: esp

Discussion

In validateToken, my code checks the token, then calls next() if everything is OK, or modifies res as json to return a specific error code.

a) Is this a correct use of middleware? b) is there a [correct] way of passing a value onto the next function?

Yes that is the correct way of using middleware, although depending on the response message type and specifications you could use the built in error handling of connect. That is in this example generate a 401 status code by calling next({status:401,stack:'Unauthorized'});

The middleware system is designed to handle the request by going through a series of functions until one function replies to the request. This is why the next function only takes one argument which is error

-> if an error object is passed to the next function then it will be used to create a response and no further middleware will be processed. The manner in which error response is created is as follows

// default to 500 if (res.statusCode < 400) res.statusCode = 500; debug('default %s', res.statusCode); // respect err.status if (err.status) res.statusCode = err.status; // production gets a basic error message var msg = 'production' == env ? http.STATUS_CODES[res.statusCode] : err.stack || err.toString();

-> to pass values down the middleware stack modifying the request object is the best method. This ensures that all processing is bound to that specific request and since the request object goes through every middleware function it is a good way to pass information down the stack.

Discussion courtesy of: DeadAlready

This recipe can be found in it's original form on Stack Over Flow .

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

点击收藏

LAST wxPython: Changing Custom Renderers for Columns / Rows vuejs - 为vuex 实现带参数的 getter , 和 state.commit NEXT