React dev server не отправляет формы прокси - PullRequest
0 голосов
/ 21 сентября 2018

Я создал приложение реагирования с помощью create-реагировать-приложение, и мой прокси-сервер работает нормально при отправке запросов с помощью axios.

Что я хочу сделать, это «обычная» отправка формы (без функции onsubmit с помощью axios),Я хочу сделать это, потому что мой сервер Node.js будет перенаправлять меня (axios не будет отправлять пользователя / браузера на перенаправление, а будет просто выполнять его через запросы, которые мне не нужны)

Когда мойформа отправляется, она просто отправляется на мой dev-сервер localhost:3000/login вместо моего сервера узлов localhost:8080/login, и я верю, что это потому, что

Сервер разработки будет пытаться отправлять запросы только без текста / html вего заголовок Accept для прокси.

source

И я вижу, что запрос от моего представления формы действительно имеет этот заголовок, и, вероятно, поэтому его игнорированиеЭто.

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

Есть ли способ сделать "нормальную" отправку формы, которая передается на мой сервер узлов вместо сервера dev?

Я думаю, что это будет работать в производстве, так как всеработает на том же сервере там, так что я думаю, почему он будет работать в производстве, но не будет возможности в разработке?

Вот как выглядит моя форма

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/"

1 Ответ

0 голосов
/ 22 сентября 2018

Поскольку вы переходите на интерфейсную маршрутизацию, я бы рекомендовал интегрировать react-router (я предпочитаю v3.0.4, а не v4.x) для обработки только интерфейсной маршрутизации и express (или что выиспользование) для обработки только внутренних запросов API.

Следующий пример предназначен только для демонстрации маршрутизации и не должен использоваться как есть.

Сначала настройте прокси в клиентской package.json (Основное преимущество этого состоит в том, чтобы избежать использования CORS):

"proxy": {
  "/api/*": {
    "target": "http://localhost:8080"
  }
}

Мой клиент routes будет настроен таким образом, чтобы App всегда оставался подключенным и действовал как сквозной для маршрутов children:

client / src / router / 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 в true через this.props.authenticated послеуспешный AJAX запрос, а затем перенаправить на 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);

Затем я могу аутентифицировать пользователя через passport вмой экспресс-контроллер (если пользователь не может авторизоваться)d, тогда он будет пойман в AJAX .catch() внутри handleSubmit):

server / controllers / auth.js

exports.login = (req, res, done) => passport.authenticate('local-login', (err, user) => {
                  if (err || !user) { res.status(404).json({ err: "Authentication failed." }); done(); }

                  res.status(201).send(null);
                })(req, res, done)
...