我使用create-react-app创建了一个react应用,当使用axios发送请求时,我的代理可以正常工作。
我要执行的操作是“正常”表单提交(axios没有onsubmit功能)。我想这样做是因为我的Node.js服务器随后将重定向我(axios不会将用户/浏览器发送到重定向,而只会通过我不希望的请求来跟踪它)
提交表单后,它只会转到我的开发服务器localhost:3000/login
而不是我的节点服务器localhost:8080/login
,我相信这是因为
开发服务器将仅尝试将其Accept标头中没有text / html的请求发送到代理。
我看到表单提交的请求确实包含该标头,这可能就是为什么它忽略它的原因。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
是否可以通过代理服务器而不是开发服务器进行“常规”表单提交?
我认为这可以在生产环境中使用,因为它们全部都在同一台服务器上运行,所以我在想为什么它可以在生产环境中工作,但是在开发中没有可能性?
这是我的表格的样子
render() {
return <div>
<Form action='/login' className="some-class">
<Button type="submit" className="some-class">
Log In
</Button>
</Form>
</div>
}
这是我的代理配置在package.json中的样子
"proxy": "https://localhost:8080/"
答案 0 :(得分:1)
由于您正在进入前端路由,所以建议您集成react-router
(我更喜欢v3.0.4而不是v4.x)来处理前端路由,而express
(或(无论您使用的是哪种方式)仅用于处理后端API请求。
以下示例仅用于路由演示目的,不应按原样使用。
首先,在客户端的package.json
中设置代理(这样做的主要优点是避免使用CORS
):
"proxy": {
"/api/*": {
"target": "http://localhost:8080"
}
}
将设置我的客户端routes
,以使App
始终保持挂载状态,并像children
路由的直通一样:
client / src / routes / index.js
import React from 'react';
import { Route } from 'react-router';
import App from '../components/App';
import Dashboard from '../components/Dashboard';
import NotFound from '../components/NotFound';
export default (
<Route path="/" component={App}>
<Route path="dashboard" component={Dashboard} />
<Route path="*" component={NotFound} />
</Route>
);
在我的App.js
中,我可以使用isAuthenticated
状态检查:
client / src / components / App.js
import React, { Component, Fragment } from 'react';
import { browserHistory } from 'react-router';
import LoginForm from './LoginForm'
export default class App extends Component {
state = { isAuthenticated: false };
componentDidMount = () => !this.state.isAuthenticated && browserHistory.push('/')
componentDidUpdate = (prevProps, prevState) => !this.state.isAuthenticated && browserHistory.push('/')
authenticated = () => this.setState({ isAuthenticated: true }, () => browserHistory.push('/dashboard'))
render = () => (
!this.state.isAuthenticated
? <LoginForm authenticated={this.authenticated} />
: <Fragment>
{this.props.children}
</Fragment>
)
}
然后,在LoginForm
组件中,我可以根据成功的isAuthenticated
请求通过this.props.authenticated
将AJAX
设置为true,然后重定向到dashboard
:
client / src / components / LoginForm.js
import React, {Component} from 'react';
import axios from 'axios';
export default class LoginForm extends Component {
state = {
login: "",
password: ""
}
handleChange = e => this.setState({ [e.target.name]: e.target.value })
handleSubmit = e => {
e.preventDefault();
const { login, password } = this.state;
if (!login || !password ) return;
axios.post('/api/login', { login, password })
.then(() => this.props.authenticated())
.catch(err => console.error(err.toString()))
}
render = () => (
<form onSubmit={this.handleSubmit} className="some-class">
<input
name="login"
type="text"
value={this.state.login}
placeholder="Username"
onChange={this.handleChange}
/>
<input
name="password"
type="password"
value={this.state.password}
placeholder="Password"
onChange={this.handleChange}
/>
<button type="submit" className="some-class">
Log In
</button>
</form>
)
}
然后,快递服务器routes
将寻找POST
请求:
服务器/路由/auth.js
const { login } = require('../controllers/auth.js');
app.post('/login', login);
然后,我可以通过我的Express控制器中的passport
对用户进行身份验证(如果无法对用户进行身份验证,那么它将被{{1}内的AJAX .catch()
中捕获) }):
服务器/控制器/auth.js
handleSubmit