簡體   English   中英

API不接受Express中來自Form的數據

[英]API not accepting data from Form in express

我有如下所示的api,我遇到的問題是,當我使用車把創建表單並將表單提交到此API時,我知道它正在擊中api,因為它顯示了驗證消息,但不接受提供的值形式:

exports.register = function (req, res, next) {
  var username = _.get(req.body, 'username');
  var password = _.get(req.body, 'password');

  if (!username) {
    throw {username: 'This field is required.', status: 400};
  }
  if (!password) {
    throw {password: 'This field is required.', status: 400};
  }

  Users.register(dbUtils.getSession(req), username, password)
    .then(response => writeResponse(res, response, 201))
    .catch(next);
};

因此,基本上是一個簡單的注冊api,該表單要求輸入用戶名和密碼,然后單擊“提交”。

以下是我的把手文件的代碼:

<div class="row">
    <div class="col-md-6 mx-auto">
        <div class="card card-body">

            <h3 class="text-center">Account Register</h3>
            <form action="/api/v0/register" method="POST" enctype='application/json'>
                <div class="form-group">
                    <label for="name">Name</label>
                    <input type="text" class="form-control" name="username" value="{{name}}" required>
                </div>

                <div class="form-group">
                    <label for="password">Password</label>
                    <input type="password" class="form-control" name="password" value="{{password}}" required>
                </div>


                <button type="submit" class="btn btn-primary">Submit</button>

            </form>
        </div>
    </div>
</div>

當我單擊“提交”頁面時,顯示我的路線的響應,要求提供用戶名。 我感到困惑的是,為什么路由未檢測到用戶名和密碼:

信息:

{
"username": "This field is required."
}

我正在使用Nodejs,Express,Express把手。

我的完整app.js如下:

var express = require('express')
  , path = require('path')
  , routes = require('./routes')
  , nconf = require('./config')
  , swaggerJSDoc = require('swagger-jsdoc')
  , methodOverride = require('method-override')
  , errorHandler = require('errorhandler')
  , bodyParser = require('body-parser')
  , setAuthUser = require('./middlewares/setAuthUser')
  , neo4jSessionCleanup = require('./middlewares/neo4jSessionCleanup')
  , writeError = require('./helpers/response').writeError;

  const exphbs = require('express-handlebars');


var app = express()
  , api = express();

app.use(nconf.get('api_path'), api);

// Handlebars middleware
app.engine('handlebars', exphbs({
  defaultLayout: 'main'
}));
app.set('view engine', 'handlebars');

// Body Parser middleware
app.use(bodyParser.urlencoded({ extended: false}));
app.use(bodyParser.json());

var swaggerDefinition = {
  info: {
    title: 'Neo4j Movie Demo API (Node/Express)',
    version: '1.0.0',
    description: '',
  },
  host: 'localhost:3000',
  basePath: '/',
};

// options for the swagger docs
var options = {
  // import swaggerDefinitions
  swaggerDefinition: swaggerDefinition,
  // path to the API docs
  apis: ['./routes/*.js'],
};

// initialize swagger-jsdoc
var swaggerSpec = swaggerJSDoc(options);

// serve swagger
api.get('/swagger.json', function(req, res) {
  res.setHeader('Content-Type', 'application/json');
  res.send(swaggerSpec);
});

app.use('/docs', express.static(path.join(__dirname, 'swaggerui')));
app.set('port', nconf.get('PORT'));

//api.use(bodyParser.json());
api.use(methodOverride());

//enable CORS
api.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Credentials", "true");
  res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT,DELETE");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
  next();
});

//api custom middlewares:
api.use(setAuthUser);
api.use(neo4jSessionCleanup);


// User Register Route
app.get('/users/register', (req, res) => {

  res.render('users/register');
});

//api routes
api.post('/register', routes.users.register);
api.post('/login', routes.users.login);
api.get('/users/me', routes.users.me);
api.get('/movies', routes.movies.list);
api.get('/movies/recommended', routes.movies.getRecommendedMovies);
api.get('/movies/rated', routes.movies.findMoviesRatedByMe);
api.get('/movies/:id',  routes.movies.findById);
api.get('/movies/genre/:id',  routes.movies.findByGenre);
api.get('/movies/daterange/:start/:end', routes.movies.findMoviesByDateRange);
api.get('/movies/directed_by/:id', routes.movies.findMoviesByDirector);
api.get('/movies/acted_in_by/:id', routes.movies.findMoviesByActor);
api.get('/movies/written_by/:id', routes.movies.findMoviesByWriter);
api.post('/movies/:id/rate', routes.movies.rateMovie);
api.delete('/movies/:id/rate', routes.movies.deleteMovieRating);
api.get('/people', routes.people.list);
api.get('/people/:id', routes.people.findById);
api.get('/people/bacon', routes.people.getBaconPeople);
api.get('/genres', routes.genres.list);

//api error handler
api.use(function(err, req, res, next) {
  if(err && err.status) {
    writeError(res, err);
  }
  else next(err);
});

app.listen(app.get('port'), () => {
  console.log('Express server listening on port ' + app.get('port') + ' see docs at /docs');
});

這是用戶的用戶路由文件:

var Users = require('../models/users')
  , writeResponse = require('../helpers/response').writeResponse
  , writeError = require('../helpers/response').writeError
  , loginRequired = require('../middlewares/loginRequired')
  , dbUtils = require('../neo4j/dbUtils')
  , _ = require('lodash');


exports.register = function (req, res, next) {


  var username = _.get(req.body, 'username');
  var password = _.get(req.body, 'password');

  if (!username) {
    throw {username: 'This field is required.', status: 400};
  }
  if (!password) {
    throw {password: 'This field is required.', status: 400};
  }

  Users.register(dbUtils.getSession(req), username, password)
    .then(response => writeResponse(res, response, 201))
    .catch(next);
};


exports.login = function (req, res, next) {
  var username = _.get(req.body, 'username');
  var password = _.get(req.body, 'password');

  if (!username) {
    throw {username: 'This field is required.', status: 400};
  }
  if (!password) {
    throw {password: 'This field is required.', status: 400};
  }

  Users.login(dbUtils.getSession(req), username, password)
    .then(response => writeResponse(res, response))
    .catch(next);
};


exports.me = function (req, res, next) {
  loginRequired(req, res, () => {
    var authHeader = req.headers['authorization'];
    var match = authHeader.match(/^Token (\S+)/);
    if (!match || !match[1]) {
      throw {message: 'invalid authorization format. Follow `Token <token>`', status: 401};
    }

    var token = match[1];
    Users.me(dbUtils.getSession(req), token)
      .then(response => writeResponse(res, response))
      .catch(next);
  })
};

這是我的用戶模型文件:

"use strict"

var uuid = require('node-uuid');
var randomstring = require("randomstring");
var _ = require('lodash');
var dbUtils = require('../neo4j/dbUtils');
var User = require('../models/neo4j/user');
var crypto = require('crypto');

var register = function (session, username, password) {
  return session.run('MATCH (user:User {username: {username}}) RETURN user', {username: username})
    .then(results => {
      if (!_.isEmpty(results.records)) {
        throw {username: 'username already in use', status: 400}
      }
      else {
        return session.run('CREATE (user:User {id: {id}, username: {username}, password: {password}, api_key: {api_key}}) RETURN user',
          {
            id: uuid.v4(),
            username: username,
            password: hashPassword(username, password),
            api_key: randomstring.generate({
              length: 20,
              charset: 'hex'
            })
          }
        ).then(results => {
            return new User(results.records[0].get('user'));
          }
        )
      }
    });
};

var me = function (session, apiKey) {
  return session.run('MATCH (user:User {api_key: {api_key}}) RETURN user', {api_key: apiKey})
    .then(results => {
      if (_.isEmpty(results.records)) {
        throw {message: 'invalid authorization key', status: 401};
      }
      return new User(results.records[0].get('user'));
    });
};

var login = function (session, username, password) {
  return session.run('MATCH (user:User {username: {username}}) RETURN user', {username: username})
    .then(results => {
        if (_.isEmpty(results.records)) {
          throw {username: 'username does not exist', status: 400}
        }
        else {
          var dbUser = _.get(results.records[0].get('user'), 'properties');
          if (dbUser.password != hashPassword(username, password)) {
            throw {password: 'wrong password', status: 400}
          }
          return {token: _.get(dbUser, 'api_key')};
        }
      }
    );
};

function hashPassword(username, password) {
  var s = username + ':' + password;
  return crypto.createHash('sha256').update(s).digest('hex');
}

module.exports = {
  register: register,
  me: me,
  login: login
};

我也嘗試過console.log req.body.username,由於某種原因,它是未定義的。

您的中間件:

// Body Parser middleware
app.use(bodyParser.urlencoded({ extended: false}));
app.use(bodyParser.json());

需要在將api路由器插入路由鏈之前。 就像您現在擁有的那樣,請求將路由到您的api路由器,而無需執行此中間件。

因此,應該是這樣的:

// Body Parser middleware
// must come before any requests, middleware or routers that want to use
// the body-parser middleware results
app.use(bodyParser.urlencoded({ extended: false}));
app.use(bodyParser.json());

app.use(nconf.get('api_path'), api);

另外,更改此:

, api = express();

至:

, api = express.Router();

因此,您只是使用路由器而不是應用程序對象。 該應用程序對象也是一個路由器,但是純路由器確實是您想要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM