req.body没有填充在express.js中 - 似乎我没有正确使用正文解析器?

时间:2015-02-18 07:07:25

标签: javascript angularjs node.js mongodb express

我一直在研究Express 4应用程序(在前端有角度)但由于某种原因,req.body没有被填充。这是我的server.js:



// Import dependencies
var path = require('path');
var qs = require('querystring');
var async = require('async');
var bcrypt = require('bcryptjs');
var bodyParser = require('body-parser');
var express = require('express');
var logger = require('morgan');
var jwt = require('jwt-simple');
var moment = require('moment');
var mongoose = require('mongoose');
var request = require('request');
var SALT_WORK_FACTOR = 10;

// Config file
var config = require('./config');

// Initialize app 
var app = express();

// App configuration
app.set('port', process.env.PORT || 8080);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, '/client')));

// User schema 
var userSchema = new mongoose.Schema({
	email: { type: String, unique: true, lowercase: true },
	password: { type: String, select: false }
});

// Makes sure that our passwords are always hashed before saving to the database
// Refer to sessionBuddy's resources for more info on this 
userSchema.pre('save', function(next) {
  console.log("I'm in the pre.save() middleware");
  var user = this;

  // Only hash the password if its modified or new
  if (!user.isModified('password')) return next();

  // Generate salt
  bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
    if (err) return next(err);

    // hash the password along with the salt
    bcrypt.hash(user.password, salt, function(err, hash) {
      if (err) return next(err);

      // overwrite the cleartext password with the hashed one
      user.password = hash;
      next();
    });
  });
});

// Password verification for cleartext and hashed passwords
userSchema.methods.comparePassword = function(password, done) {
  bcrypt.compare(password, this.password, function(err, isMatch) {
    done(err, isMatch);
  });
};

// User model
var User = mongoose.model('User', userSchema);

// Connect to the db
mongoose.connect(config.MONGO_URI);
mongoose.connection.on('error', function() {
  console.error('MongoDB Connection Error. Please make sure that MongoDB is running.');
});

/*
 |--------------------------------------------------------------------------
 | Login Required Middleware
 |--------------------------------------------------------------------------
 */
function ensureAuthenticated(req, res, next){
	if(!(req.headers && req.headers.authorization)){
		return res.status(400).send({ message: 'You did not provide a JSON Web Token in the authorization header.'});
	}

	// Decode the token
	var header = req.headers.authorization.split(' ');
	var token = header[1];
	var payload = jwt.decode(token, config.TOKEN_SECRET);
	var now = moment().unix();

	// Check if the token is expired
	if(now > payload.exp){
		return res.status(401).send({ message: 'Token has expired. '});
	}

	// Check if the user still exists in the db
	User.findById(payload.sub, function(err, user){
		if(!user){
			return res.status(400).send({ message: 'User no longer exists. '});
		}

		// Attach the "user" object to the "request" object (req)
    // So now if we want to access current user's info in a protected route like
    // /api/feed we can just access "req.user" object
    // So basically every protected route like /api/feed or /api/media/:id
    // needs to first call isAuthenticated() to get the user 
    // NOTE: please check the protected routes in "server.js" of sahat's Instagram tutorial 
    req.user = user;
		next();
	})
}

/*
 |--------------------------------------------------------------------------
 | Generate JWT Token
 |--------------------------------------------------------------------------
 */
function createToken(user){
	var payload = {
		exp: moment().add(14, 'days').unix(),
		iat: moment().unix(),
		sub: user._id
	};

	return jwt.encode(payload, config.TOKEN_SECRET);
}

/*
 |--------------------------------------------------------------------------
 | Signup Route (/api/signup)
 |--------------------------------------------------------------------------
 */
app.post('/auth/signup', function(req, res){
	console.log("This is the email we recieve in /auth/signup ->", req.body.email);

	// First make sure there are no accounts with same email already registered
	User.findOne({ email: req.body.email }, function(err, existingUser){
		// If found a user (with the same email)
		if(existingUser){
			console.log('Email already taken');
			return res.status(409).send({ message: 'Email is already taken' });
		}

		// Make a user object
		// NOTE: don't worry about hashing the password before saving here because
		// we already have a pre.save() middleware on the userSchema that makes sure
		// that all passwords are hashed before being inserted
		var user = new User({
			email: req.body.email, 
			password: req.body.password
		});

		// Now save the user in the db
		// create and send a JWT token back along with the user
		user.save(function(){
			console.log("I'm in the user.save() function");
			var token = createToken(user);
			res.send({ token: token, user: user });
		});
	});
});

/*
 |--------------------------------------------------------------------------
 | Login Route (/api/login)
 |--------------------------------------------------------------------------
 */
app.post('/auth/login', function(req, res){
	// Check if the user exists
	// we do "+password" to get the password field in the result of the query back
	// We have to do this cos we did "select : false" for password earlier
	console.log("This is the email here ->", req.body.email);
	User.findOne({ email: req.body.email }, '+password', function(err, user){
		// If user wasn't found
		if(!user){
			console.log('User not found');
			return res.status(401).send({ message: { email: 'Incorrect email' } });
		}

		// Call the comparePassword() function of the userSchema to check if the passwords match
		user.comparePassword(req.body.password, function(err, isMatch){
			// Passwords didn't match
			if(!isMatch){
				console.log("Passwords didn't match");
				return res.status(401).send({ message: 'Wrong email and/or password' });
			}

			// Passwords matched
			// Send a JWT token back
			var token = createToken(user);
			res.send({ token: token });
		})

	})
});

app.get('*', function(req, res) {
	res.sendFile(path.join(__dirname + '/client/index.html'));
});

// Start the server
app.listen(app.get('port'), function() {
  console.log('Express server listening on port ' + app.get('port'));
});




这是我的注册表单



<div class="container">
    <br/>
    
    <div class="row">
    
        <div class="center-form panel">
        
            <form method="post" ng-submit="signup()" name="signupForm">
            
                <div class="panel-body">
                
                    <h2 class="text-center">Sign up</h2>
                    
                    <!-- Email -->
                    <div class="form-group" ng-class="{ 'has-success' : signupForm.email.$valid && signupForm.email.$dirty, 'has-error' : signupForm.email.$invalid && signupForm.email.$dirty }">  
                        <!-- Email input -->
                        <input class="form-control input-lg" type="email" id="email" name="email" ng-model="email" placeholder="Email" required autofocus>
                        <!-- Email ngmessage -->
                        <div class="help-block text-danger" ng-if="signupForm.email.$dirty" ng-messages="signupForm.email.$error">
                            <div ng-message="required">Sorry, email address is required</div>
                            <div ng-message="email">Sorry, the email address you entered is invalid</div>
                        </div>    
                    </div>
                    
                    <!-- Password -->
                    <div class="form-group" ng-class="{ 'has-success' : signupForm.password.$valid && signupForm.password.$dirty, 'has-error' : signupForm.password.$invalid && signupForm.password.$dirty }">
                        <!-- Password input -->
                        <input class="form-control input-lg" type="password" name="password" ng-model="password" placeholder="Password" required>
                        <!-- Password ngmessage -->
                        <div class="help-block text-danger" ng-if="signupForm.password.$dirty" ng-messages="signupForm.password.$error">
                            <div ng-message="required">Sorry, password is required.</div>
                        </div>
                    </div>
                    
                    <!-- Confirm Password -->
                    <div class="form-group" ng-class="{ 'has-success' : signupForm.confirmPassword.$valid && signupForm.confirmPassword.$dirty, 'has-error' : signupForm.confirmPassword.$invalid && signupForm.confirmPassword.$dirty }">
                        <!-- Confirm Password input -->
                        <input class="form-control input-lg" type="password" name="confirmPassword" ng-model="confirmPassword" repeat-password="password" placeholder="Confirm Password" required>
                        <!-- Confirm Password ngmessage -->
                        <div class="help-block text-danger" ng-if="signupForm.confirmPassword.$dirty" ng-messages="signupForm.confirmPassword.$error">
                            <div ng-message="required">Sorry, you must confirm password.</div>
                            <div ng-message="repeat">Sorry, passwords do not match</div>
                        </div>
                    </div>
                    
                    <!-- Button -->
                    <button type="submit" ng-disabled="signupForm.$invalid" class="btn btn-lg btn-block btn-primary">Create Account</button>
                </div>
                
            </form>
            
        </div>
    
    </div>
</div>
&#13;
&#13;
&#13;

这是我的注册控制器

&#13;
&#13;
angular.module('MyApp')
	.controller('SignupCtrl', function($scope, $auth){

		console.log("I'm in Signup controller");
		console.log("This is the email I get in signup controller", $scope.email);

		// get the "user" object from the view
		var user = {
			email : $scope.email,
			password: $scope.password
		};

		console.log(user);

		// signup function
		$scope.signup = function(){
		
		console.log("I'm in Signup controller");
		console.log("This is the email I get in signup()", $scope.email);

			// call the signup() function from the $auth service (Which is part of Satellizer)
			$auth.signup(user)
				.then(function(response){
					console.log(response.data);
				});
		};

	});
&#13;
&#13;
&#13;

在我通过输入电子邮件和密码运行注册表单后,我注意到在请求通过注册控制器之前,它具有电子邮件的值(请参见下图)

enter image description here

然而,在/ auth / signup路由中,req.body.email的值仍未定义(请参见下图)

enter image description here

我也尝试使用谷歌搜索/搜索stackoverflow,但还没有能够解决它。

感谢您的帮助!

编辑1:这是发布请求的正文

&#13;
&#13;
{
  "log": {
    "version": "1.2",
    "creator": {
      "name": "WebInspector",
      "version": "537.36"
    },
    "pages": [],
    "entries": [
      {
        "startedDateTime": "2015-02-18T07:33:14.106Z",
        "time": 30.250072479248047,
        "request": {
          "method": "POST",
          "url": "http://localhost:8080/auth/signup",
          "httpVersion": "HTTP/1.1",
          "headers": [
            {
              "name": "Origin",
              "value": "http://localhost:8080"
            },
            {
              "name": "Accept-Encoding",
              "value": "gzip, deflate"
            },
            {
              "name": "Host",
              "value": "localhost:8080"
            },
            {
              "name": "Accept-Language",
              "value": "en-US,en;q=0.8"
            },
            {
              "name": "User-Agent",
              "value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36"
            },
            {
              "name": "Content-Type",
              "value": "application/json;charset=UTF-8"
            },
            {
              "name": "Accept",
              "value": "application/json, text/plain, */*"
            },
            {
              "name": "Referer",
              "value": "http://localhost:8080/"
            },
            {
              "name": "Connection",
              "value": "keep-alive"
            },
            {
              "name": "Content-Length",
              "value": "2"
            }
          ],
          "queryString": [],
          "cookies": [],
          "headersSize": 448,
          "bodySize": 2,
          "postData": {
            "mimeType": "application/json;charset=UTF-8",
            "text": "{}"
          }
        },
        "response": {
          "status": 200,
          "statusText": "OK",
          "httpVersion": "HTTP/1.1",
          "headers": [
            {
              "name": "Date",
              "value": "Wed, 18 Feb 2015 07:33:14 GMT"
            },
            {
              "name": "Connection",
              "value": "keep-alive"
            },
            {
              "name": "X-Powered-By",
              "value": "Express"
            },
            {
              "name": "Content-Length",
              "value": "226"
            },
            {
              "name": "Content-Type",
              "value": "application/json; charset=utf-8"
            }
          ],
          "cookies": [],
          "content": {
            "size": 226,
            "mimeType": "application/json",
            "compression": 0
          },
          "redirectURL": "",
          "headersSize": 171,
          "bodySize": 226
        },
        "cache": {},
        "timings": {
          "blocked": 2.55699999979697,
          "dns": -1,
          "connect": -1,
          "send": 0.11399999857531018,
          "wait": 26.36900000288732,
          "receive": 1.2100724779884473,
          "ssl": -1
        },
        "connection": "274032"
      }
    ]
  }
}
&#13;
&#13;
&#13;

编辑2:这是使用firebug的req主体的另一个屏幕截图

enter image description here

编辑3:因为@Quest建议我在signup()函数之外初始化用户对象,这就是它发送空POST数据的原因。所以当我把它移到函数内部时(包括signup()和login()),它们现在都可以工作了。

0 个答案:

没有答案