我正在通过动作创建者中的axios向我的快速后端进行api请求。 我可以看到该请求已在后端登录(但没有状态)并成功通过,但是响应从未返回到前端(在浏览器控制台中看不到LOGIN_SUCCESS输出)。 当我在本地模拟curl上的相同请求时,它工作得很好,并返回200条消息。
前端:
./ actions / index.js
const loginRequested = function () {
console.log(LOGIN_REQUESTED)
return {
type: LOGIN_REQUESTED,
loading: true,
}
}
const loginSuccess = function () {
console.log(LOGIN_SUCCESS)
return {
type: LOGIN_SUCCESS,
isAuthUser: true,
}
}
export const login = ({ email, password }) => {
return dispatch => {
dispatch(loginRequested());
axios.post('http://localhost:9000/login', {
username: email,
password: password,
}).then(response => {
console.log('This has been reached')
dispatch(loginSuccess(response));
}).catch(err => {
console.log('An error took place: ', err)
})
}
}
登录组件:
import React, { Component } from 'react';
import Button from 'react-bootstrap/Button';
import { connect } from 'react-redux';
import Form from 'react-bootstrap/Form';
import { login } from './actions/index'
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
}
this.setEmail = this.setEmail.bind(this);
this.setPassword = this.setPassword.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit() {
this.props.login({
email: this.state.email,
password: this.state.password,
})
}
setEmail(e) {
this.setState({ email: e.target.value });
}
setPassword(e) {
this.setState({ password: e.target.value });
}
render() {
return (
<Form className="Form" onSubmit={this.handleSubmit}>
<Form.Group controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control
autoFocus
type="email"
name="email"
placeholder="Enter email"
onChange={this.setEmail}
/>
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
name="password"
placeholder="Password"
onChange={this.setPassword}
/>
</Form.Group>
<Form.Group controlId="formBasicCheckbox">
<Form.Check type="checkbox" label="Remember Password" />
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
);
}
}
const mapDispatchToProps = dispatch => {
return {
login: user => {
dispatch(login(user));
}
}
}
const mapStateToProps = state => {
return {
isAuthUser: state.isAuthUser,
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Login);
我也在使用redux-thunk支持异步操作:
const store = createStore(rootReducer, applyMiddleware(thunk));
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
后端:
app.js:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require('cors');
var homeRouter = require('./routes/home')
var loginRouter = require('./routes/login');
var registerRouter = require('./routes/register')
var db = require('./repositories/db');
var app = express();
// Connect to DB
require('./repositories/db')
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// app.use('/', indexRouter);
// app.use('/users', usersRouter);
app.use('/home', homeRouter);
app.use('/login', loginRouter);
app.use('/register', registerRouter)
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
routes / login.js:
router.post('/', function (req, res, next) {
User.findOne({ email: req.body.username }).then(
(user) => {
if (!user) {
return res.status(401).json({
error: new Error('User not found!')
});
}
bcrypt.compare(req.body.password, user.password).then(
(valid) => {
username = req.body.username;
if (!valid) {
return res.status(401).json({
error: new Error('Incorrect password!')
});
}
const token = jwt.sign({ username }, jwtKey, {
algorithm: 'HS256',
expiresIn: jwtExpirySeconds,
});
console.log('User successfully logged in.');
res.cookie('token', token, { maxAge: jwtExpirySeconds * 1000 });
res.send({ message: 'We did it!' })
}
).catch(
(err) => {
console.log('Error logging in: ', err);
res.status(500).json({
error: err
});
}
);
}
).catch(
(err) => {
res.status(500).json({
error: err
});
}
);
});
curl请求:
curl -X POST -H 'Content-Type: application/json' -d '{
"username": "a@a.com",
"password": "qwer1234"
}' -v -i 'http://localhost:9000/login'
curl的输出:
User successfully logged in.
POST /login 200 61.225 ms - 24
上述程序化API请求的输出:
POST /login - - ms - -
User successfully logged in.