Node.js 为什么nodejs即使在处理路由请求后仍返回404?
我正在为我的后端API使用Node.js 为什么nodejs即使在处理路由请求后仍返回404?,node.js,express,Node.js,Express,我正在为我的后端API使用jwtwebtoken、express、mongo、nodejs、bcrypt。我注意到我为localhost:3000/account/updatepath配置的路由器正在执行,但成功运行后返回404。数据库连接正常。但是postman中的localhost:3000/account/update路由得到404为什么 server.js const express = require('express'); const app = express(); const b
jwtwebtoken
、express
、mongo
、nodejs
、bcrypt
。我注意到我为localhost:3000/account/update
path配置的路由器正在执行,但成功运行后返回404。数据库连接正常。但是postman中的localhost:3000/account/update
路由得到404为什么
server.js
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const dbUtils = require('./services/dbconnect');
module.exports = app;
// get an instance of the router for account api routes.
const accountRoutes = require('./services/account');
const registerRoutes = require('./services/register');
const authenticateRoutes = require('./services/authentication');
// used to create, sign, and verify tokens
const jwt = require('jsonwebtoken');
// Secret key to generate new tockens.
app.set('superSecret', "11111"); // secret variable
// parse application/json
app.use(bodyParser.json())
app.use('/account', accountRoutes);
app.use('/authenticate', authenticateRoutes);
app.use('/register', registerRoutes);
app.get('/', (req, res) => res.send('Hello World!'));
dbUtils.connectToServer(() =>{
app.listen(3000, () => console.log('Server listening on port 3000!'));
});
each-request.js
const jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
const app = require('./../server');
function verifyLoginTokenForEachRequest(req, res, next) {
// check header parameters for token
const token = req.headers['x-access-token'];
try {
if (token) {
// verifies secret and checks exp
jwt.verify(token, app.get('superSecret'), (err, decoded) => {
console.log(decoded);
if (err) {
throw err || new Error('not authorized')
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
console.log("[authorized] user logged in")
next();
}
});
} else {
// if there is no token, return an error
return res.status(403).send({msg: "not authorized"});
}
} catch(e) {
console.log("[unauthorized]", e);
return res.status(401).json({ msg: 'Failed to authenticate token.' });
} finally{
next();
}
}
module.exports={verifyLoginTokenForEachRequest};
account.js
const express = require('express')
const router = express.Router();
const verifyLoginTokenForEachRequest = require('./each-request').verifyLoginTokenForEachRequest;
const dbUtils = require('./dbconnect');
router.use(verifyLoginTokenForEachRequest);
router.post('/update', (req, res) => {
const body = req.body;
const db = dbUtils.getDb();
console.log(body);
try {
db.collection('users')
.updateOne({emailid: body.emailid},{$set:{firstName: body.firstName, lastName: body.lastName, lastModified: body.lastModified}},function(err, doc){
if(err || !doc) {
console.log(err);
throw err || new Error('Failed to update')
} else {
console.log("[success] update success");
console.log(doc)
res.status(200).send();
}
});
} catch(e) {
console.error("[error] failed to update");
res.status(500).send({msg: 'failed to update'});
}
});
module.exports = router;
我认为这里有很多问题是错误的。我不确定哪些问题确实符合或不符合您的要求,但您需要首先解决这些问题,然后看看还剩下什么问题(如果有)
verifyLoginTokenForEachRequest()
函数总是调用next()
,即使它已经发送了401或403响应。如果发送响应,不要调用next()
next()
告诉Express继续走下一条路线。一旦您发送了响应,您就完成了。停止进一步的路由。不要调用next()
verifyLoginTokenForEachRequest()
中,您试图创建一个错误条件,方法是在异步回调中执行抛出xxx
,然后期望在更高级别捕获该错误。那是行不通的。异常将返回到jwt.verify()
的内部,而不会进入异常处理程序。异步异常(除非它们是promise.then()
处理程序的一部分)将不会出现。你不能在更高的水平上投球和接球。你必须在它们发生的地方处理它们。在这种情况下,您应该直接在那里发送错误响应verifyLoginTokenForEachRequest()
中,您在finally子句中调用next()
,而您很可能已经发送了响应。仅当您希望继续路由到其他路由处理程序且尚未发送响应时,才调用next()
router.post('/update',…)
中,您再次在异步回调中抛出异常,异常处理程序将不会捕获该异常。不能那样做。将错误响应发送到那里或使用承诺,以便更容易地将错误传播到更高的级别verifyLoginTokenForEachRequest()
:
下面是account.js的固定版本:
const express = require('express')
const router = express.Router();
const verifyLoginTokenForEachRequest = require('./each-request').verifyLoginTokenForEachRequest;
const dbUtils = require('./dbconnect');
router.use(verifyLoginTokenForEachRequest);
router.post('/update', (req, res) => {
const body = req.body;
const db = dbUtils.getDb();
console.log(body);
db.collection('users')
.updateOne({emailid: body.emailid},{$set:{firstName: body.firstName, lastName: body.lastName, lastModified: body.lastModified}},function(err, doc){
if(err || !doc) {
console.error("[error] failed to update", err);
res.status(500).send({msg: 'failed to update'});
} else {
console.log("[success] update success");
console.log(doc);
res.end();
}
});
});
module.exports = router;
我认为这里有很多问题是错误的。我不确定哪些问题确实符合或不符合您的要求,但您需要首先解决这些问题,然后看看还剩下什么问题(如果有)
verifyLoginTokenForEachRequest()
函数总是调用next()
,即使它已经发送了401或403响应。如果发送响应,不要调用next()
next()
告诉Express继续走下一条路线。一旦您发送了响应,您就完成了。停止进一步的路由。不要调用next()
verifyLoginTokenForEachRequest()
中,您试图创建一个错误条件,方法是在异步回调中执行抛出xxx
,然后期望在更高级别捕获该错误。那是行不通的。异常将返回到jwt.verify()
的内部,而不会进入异常处理程序。异步异常(除非它们是promise.then()
处理程序的一部分)将不会出现。你不能在更高的水平上投球和接球。你必须在它们发生的地方处理它们。在这种情况下,您应该直接在那里发送错误响应verifyLoginTokenForEachRequest()
中,您在finally子句中调用next()
,而您很可能已经发送了响应。仅当您希望继续路由到其他路由处理程序且尚未发送响应时,才调用next()
router.post('/update',…)
中,您再次在异步回调中抛出异常,异常处理程序将不会捕获该异常。不能那样做。将错误响应发送到那里或使用承诺,以便更容易地将错误传播到更高的级别verifyLoginTokenForEachRequest()
:
下面是account.js的固定版本:
const express = require('express')
const router = express.Router();
const verifyLoginTokenForEachRequest = require('./each-request').verifyLoginTokenForEachRequest;
const dbUtils = require('./dbconnect');
router.use(verifyLoginTokenForEachRequest);
router.post('/update', (req, res) => {
const body = req.body;
const db = dbUtils.getDb();
console.log(body);
db.collection('users')
.updateOne({emailid: body.emailid},{$set:{firstName: body.firstName, lastName: body.lastName, lastModified: body.lastModified}},function(err, doc){
if(err || !doc) {
console.error("[error] failed to update", err);
res.status(500).send({msg: 'failed to update'});
} else {
console.log("[success] update success");
console.log(doc);
res.end();
}
});
});
module.exports = router;