【问题标题】:Cannot POST error on form submit with nodejs backend使用nodejs后端提交表单时无法POST错误
【发布时间】:2018-05-14 18:46:21
【问题描述】:

我正在使用以下堆栈:

  • 反应
  • PassportJS
  • NodeJS
  • 快速和快速会话
  • create-react-app 与 webpack 开发服务器代理 API 请求到我的节点服务器,如 article 中所述

当我提交表单时,我收到一个错误 Cannot POST 但是当我使用 POSTMAN 或 curl XPOST 提交到相同的 url 时,我得到了结果。这是我的 server.js 代码:

'use strict';

const PORT = process.env.PORT || 3001;
const express = require('express');
const app = express();
const path = require('path');
const passport = require('passport')
const initPassport = require('./passport/init');
const session = require('express-session')
const mongoose = require('mongoose');
const bodyParser   = require('body-parser');
const cookieParser = require('cookie-parser')
const configDB = require('./config/database.js');
const MongoStore = require('connect-mongo')(session);
var flash = require('connect-flash');

//Connect to mongo
mongoose.connect(configDB.url, {
  useMongoClient: true
}).then(() => console.log('connection with database succeeded'))
.catch(err => console.error(err));


// Initialize Passport
initPassport(passport);

// Serve static assets
app.use(express.static(path.resolve(__dirname, '..', 'build')));


//use cookie parser to store data
app.use(cookieParser());
app.use(session({ 
  secret: 'mysecret',
  store : new MongoStore ({
    db : mongoose.connection.db,
    host : '127.0.0.1',
    port : '27017',
    url : configDB.url
  }),
  maxAge : 2 * 60 * 60 * 1000,
  resave: false,
  saveUninitialized: false
})); // session secret

app.use(bodyParser.urlencoded({ extended: false })); 
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session

app.post('/signup', passport.authenticate('signup', {
  successRedirect: '/',
  failureRedirect: '/signup'
}));

app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}!`);
});

表格页面:

import React, { Component } from 'react';
import constants from 'constants/AuthPageConstants';

class RegisterForm extends Component {
    render() {
        return (
            <div className="tab-pane fade in" id="basic-tab2">
                <form action="/signup" method="POST">
                    <div className="text-center">
                        <div className="icon-object border-success text-success"><i className="icon-plus3"></i></div>
                        <h5 className="content-group">{constants.register_form_title} <small className="display-block">{constants.register_form_subtitle}</small></h5>
                    </div>

                    <div className="form-group has-feedback has-feedback-left">
                        <input type="text" name="username" className="form-control" placeholder={constants.register_username_placeholder} />
                        <div className="form-control-feedback">
                            <i className="icon-user-check text-muted"></i>
                        </div>
                    </div>

                    <div className="form-group has-feedback has-feedback-left">
                        <input type="password" name="password" className="form-control" placeholder={constants.register_password_placeholder} />
                        <div className="form-control-feedback">
                            <i className="icon-user-lock text-muted"></i>
                        </div>
                    </div>

                    <div className="form-group has-feedback has-feedback-left">
                        <input type="text" name="email" className="form-control" placeholder={constants.register_email_placeholder} />
                        <div className="form-control-feedback">
                            <i className="icon-mention text-muted"></i>
                        </div>
                    </div>

                    <div className="content-divider text-muted form-group"><span>Additions</span></div>

                    <div className="form-group">
                        <div className="checkbox">
                            <label>
                                <input type="checkbox" className="styled" />
                                {constants.tos_txt.substring(0, constants.tos_txt.indexOf(" "))} <a href="#">{constants.tos_txt.substr(constants.tos_txt.indexOf(" ") + 1)}</a>
                            </label>
                        </div>
                    </div>
                    <button type="submit" className="btn bg-indigo-400 btn-block">Register <i className="icon-circle-right2 position-right"></i></button>
                </form>
            </div>
        )
    }
}
export default RegisterForm

注册护照策略

var LocalStrategy   = require('passport-local').Strategy;
var User = require('../models/user');
var bCrypt = require('bcrypt');

module.exports = function(passport){

    passport.use('signup', new LocalStrategy({
            passReqToCallback : true // allows us to pass back the entire request to the callback
        },
        function(req, username, password, done) {
            console.log("In Signup");
            findOrCreateUser = function(){
                // find a user in Mongo with provided username
                User.findOne({ 'username' :  username }, function(err, user) {
                    // In case of any error, return using the done method
                    if (err){
                        console.log('Error in SignUp: '+err);
                        return done(err);
                    }
                    // already exists
                    if (user) {
                        console.log('User already exists with username: '+username);
                        return done(null, false, req.flash('message','User Already Exists'));
                    } else {
                        // if there is no user with that email
                        // create the user
                        var newUser = new User();

                        // set the user's local credentials
                        newUser.username = username;
                        newUser.password = createHash(password);
                        newUser.email = req.param('email');
                        newUser.firstName = "firstName";
                        newUser.lastName = "lastName";

                        // save the user
                        newUser.save(function(err) {
                            if (err){
                                console.log('Error in Saving user: '+err);  
                                throw err;  
                            }
                            console.log('User Registration succesful');    
                            return done(null, newUser);
                        });
                    }
                });
            };
            // Delay the execution of findOrCreateUser and execute the method
            // in the next tick of the event loop
            process.nextTick(findOrCreateUser);
        })
    );

    // Generates hash using bCrypt
    var createHash = function(password){
        return bCrypt.hashSync(password, bCrypt.genSaltSync(10));
    }

}

更新

问题似乎是由于代理的存在。如果我直接调用在不同端口上运行的 nodejs 后端 API(通过允许 CORS)并删除代理,则表单提交有效。如果我插入代理,并使表单指向 webback 开发服务器,那么表单提交不会调用我的 nodeJS API。但是,代理可以与 curl 和 POSTMAN 一起使用。奇怪的是 curl 是如何工作的,而表单提交却不是。此处的任何指示都会有所帮助。

【问题讨论】:

  • 不能发帖是什么意思?你得到什么错误?
  • 检查您的 Express 日志以了解发生了什么是值得的。您可能缺少传入 POST 的 Content-Type 的正确正文解析器。
  • 另外,您的表单操作正在访问一个名为 /test 的端点。我在您的节点应用程序的任何地方都没有看到它。
  • @RobertMoskal 我收到以下错误:Cannot POST /signup /test 是这里的错字,我的代码正确显示 /signup。我在上面编辑到 /signup ,这不是问题。
  • @tadman 正如您在代码中看到的那样,表单的 enctype 保留为默认值。 nodejs 代码具有用于 urlencoded 的 bodyparser。日志没有显示任何错误。

标签: node.js reactjs passport.js passport-local


【解决方案1】:

尝试清除浏览器缓存。如果您使用的是 chrome

  1. 转至settings
  2. 在搜索中输入cache
  3. 浏览到底部并清除缓存。 如果不能解决问题请回信

【讨论】:

  • 清除缓存没用
  • 这并不是真正的解决方案。它可以解决一些问题,但将其用作仪式类似于巫术。
猜你喜欢
  • 1970-01-01
  • 2020-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 2021-01-12
  • 2017-10-23
相关资源
最近更新 更多