我有两种方法:
validateRegistration(),它调用app.get(' / users /:email',todo)
login(),它调用app.get(' / users /:username',todo)
validateRegistration()工作正常,但是当调用login()时,它返回null,但是如果我在server.js中注释掉app.get(' / users /:email',todo) ,login()返回预期的响应。似乎两者都不能在server.js中一起存在
参见下面的相关代码
registerPage.html
<div class="container" ng-show="show">
<form name="registerForm" novalidate>
<h2>Registration</h2>
<span>All fields required</span>
<br>
<br>
<label>First Name</label>
<br>
<input class="form-control" type="text" ng-model="user.fName" name="fName" required placeholder="First Name">
<div ng-messages="registerForm.fName.$error">
<div class="errorMsg" ng-message="required">Required</div>
</div>
<br>
<label>Last Name</label>
<input class="form-control" type="text" ng-model="user.lName" name="lName" required placeholder="Last Name">
<div ng-messages="registerForm.lName.$error">
<div class="errorMsg" ng-message="required">Required</div>
</div>
<br>
<label>Email</label>
<input class="form-control" ng-model="user.email" ng-change="validateEmail(user.email)" type="email" name="emailAdd" required placeholder="Email">
<span class="errorMsg">{{emailExistsMsg}}</span>
<div ng-messages="registerForm.emailAdd.$error">
<div class="errorMsg" ng-message="email">Invalid email address</div>
<div class="errorMsg" ng-message="required">Required</div>
</div>
<br>
<label>Username</label>
<input class="form-control" ng-model="user.username" ng-change="validateUsername(user.username)" type="text" name="uName" required placeholder="Username">
<span class="errorMsg">{{usernameExistsMsg}}</span>
<div ng-messages="registerForm.uName.$error">
<div class="errorMsg" ng-message="required">Required</div>
</div>
<br>
<label>Password</label>
<input class="form-control" ng-minlength="6" type="password" ng-model="user.password" name="password" required placeholder="Password">
<div ng-messages="registerForm.password.$error">
<div class="errorMsg" ng-message="minlength">Password should be 6 character minimum</div>
<div class="errorMsg" ng-message="required">Required</div>
</div>
<br>
<button class="btn btn-info" ng-click="addUser(user)" ng-disabled="registerForm.$invalid">Register</button>
<br>
<br>
<a href="#/signIn">Already registered?......<strong>Log In</strong></a>
</form>
</div>
&#13;
registerController.js
myApp.controller('RegisterController', ['$scope', '$http', '$location', function($scope, $http, $location) {
console.log("Register controller");
$scope.addUser = function(user) {
console.log("Add user called");
$http.post('/users', {fname: user.fName, lname: user.lName, email: user.email, username: user.username, password: user.password}).success(function(response) {
console.log("Add user response username: " + response.username);
});
this.validateRegistration(user.email);
};
$scope.validateEmail = function(email) {
console.log("Validate email called");
$http.get('/users/' + email).success(function(response) {
if(response != null) {
$scope.emailExistsMsg = response.email + " already exists";
} else {
$scope.emailExistsMsg = "";
}
});
};
$scope.validateRegistration = function(email) {
$http.get('/users/' + email).success(function(response) {
if(response != null) {
console.log("Registration successful");
$scope.registrationMsg = "Congratulations " + email + ". Registration successful";
console.log($scope.registrationMsg);
$location.path("/registrationStatus");
} else {
console.log("Registration not successful: " + response);
$scope.registrationMsg = "Error with registration. Please try again or contact administrator.";
console.log($scope.registrationMsg);
$location.path("/registrationStatus");
}
});
};
}]);
&#13;
signinPage.html
<div class="container" ng-show="show">
<br>
<form name="signInForm" novalidate>
<h2>Sign In</h2>
<br>
<label>Username</label>
<input class="form-control" ng-model="user.username" type="text" name="username" required placeholder="Username">
<br>
<label>Password</label>
<input class="form-control" ng-model="user.password" type="password" name="password" required placeholder="Password">
<br>
<button class="btn btn-info" ng-click="logIn(user.username, user.password)" ng-disabled="signInForm.$invalid">Sign In</button>
<br>
<br>
<a href="#/register">Not registered?......<strong>Register</strong></a>
</form>
</div>
&#13;
signinController.js
myApp.controller('SignInController', ['$scope', '$http', '$location', function($scope, $http, $location) {
console.log("Sign in controller");
$scope.logIn = function(username, password) {
console.log("Sign in called");
$http.get('/users/' + username).success(function(response) {
if(response != null) {
if(username == response.username && password == response.password) {
console.log("Successful log in");
this.isDisabled = false;
$location.path("/playSet");
}
} else {
console.log("User not found: " + response);
}
});
};
}]);
&#13;
server.js
var express = require('express');
var app = express();
var mongojs = require('mongojs');
var db = mongojs('tracks', ['tracks']);
var db1 = mongojs('setlist', ['setlist']);
var db2 = mongojs('users', ['users']);
var bodyParser = require('body-parser');
app.use(express.static(__dirname = '\public'));
app.use(bodyParser.json());
app.get('/users/:email', function(req, res) {
var email = req.params.email;
console.log("Existing email validation: " + email);
db2.users.findOne({email: email}, function(err, doc) {
res.json(doc);
});
});
app.get('/users/:username', function(req, res) {
var username = req.params.username;
console.log("User: " + username);
db2.users.findOne({username: username}, function(err, doc) {
res.json(doc);
});
});
app.listen(3000);
console.log("Server running on port 3000");
&#13;
答案 0 :(得分:3)
您不能有两条不同的路线:
app.get('/users/:email', ...);
app.get('/users/:username', ...);
因为第二个不会被击中,因为第一个匹配相同的东西。您有以下选择:
如果(我只是从您的上下文中猜测一下),您尝试支持两种识别用户的方式(一个是用户名,另一个是电子邮件地址),那么我和建议您将它们组合到一个路由处理程序中,然后检查:username
值以查看它是用户名还是电子邮件地址,并在您的路由中相应地执行操作。如果用户名中不允许@
符号,但电子邮件地址中需要req.params.username
符号,则可以使用此功能。然后,您可以检查@
是否包含// single route handler to handle either a username or email lookup
app.get('/users/:username', function(req, res) {
var username = req.params.username;
if (username.indexOf("@") !== -1) {
console.log("Existing email validation: " + username);
db2.users.findOne({email: username}, function(err, doc) {
res.json(doc);
});
} else {
console.log("User: " + username);
db2.users.findOne({username: username}, function(err, doc) {
res.json(doc);
});
}
});
符号,如果是,则转移到电子邮件地址逻辑。
// single route handler to handle either a username or email lookup
app.get('/users/:username', function(req, res) {
// lookup either email address or username
let name = req.params.username;
let lookupObj = name.indexOf("@") !== -1 ? {email: name} : {username: name};
db2.users.findOne(lookupObj, function(err, doc) {
res.json(doc);
});
});
或者,或许多一点干:
app.get('/users/email/:email', ...);
app.get('/users/userID/:username', ...);
或者,您可以使用唯一路径分隔路线:
allScriptsTimeout
答案 1 :(得分:1)
这个问题已经发布 4 年多了,我也遇到了类似的问题。
我想谈谈我是如何解决这个问题的。它可能会有所帮助。简而言之,我将控制器转换为中间件。
我最初拥有的
app.get('/users/:email', ...);
app.get('/users/:id', ...);
我删除了
app.get('/users/:email', ...)
并制作成
app.get('/users', getUserByEmail, ...otherControllers)
然后,在 getUserByEmail
中,我检查 email
对象上是否存在 req.query
属性,并且如果它是查询对象上的唯一属性,则通过以下方式搜索用户电子邮件,否则,执行下一个函数以移动到下一个控制器/中间件。
if(req.query.email !== undefined && Object.keys(req.query).length === 1){
... code to get user by email
end if block with return
}
next()
答案 2 :(得分:0)
这些不是唯一的路线。
与给定路径匹配的第一个路径是使用的路径,无论提供的参数如何。
此处您的路由/users/
包含email
参数,后跟相同的路由/users/
,其中username
参数永远不会被评估。
如果要使用这种路由方式,则应该有一个/users/
路由接受参数,然后在该路由中评估参数以确定它是email
还是{ {1}},然后在数据库上执行相应的查找。这不是一种简单或万无一失的方法,并且限制了某人可以将其电子邮件地址用作用户名等的可能性。因此,您应强烈考虑使用唯一路线,例如username
或类似的路线。
就我个人而言,我认为您的问题因为您似乎希望使用/users/email/:email
进行注册和登录而更加困惑。您可能应该使用/users/
和/login/
之类的内容,尤其是以后您可以使用/register/
来获取用户列表。但是,如果必须使用相同的路线,可以将它们分隔为/users/
和get
,因为post
更为常见无论如何,还有注册类型的场景。
总的来说,感觉您需要花费更多时间来评估整体API的使用和目的,以确定构建端点的正确方法。